直入主题,先引入 nutz-spring-boot-starter 的包。
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutz-spring-boot-starter</artifactId>
<version>2.2.7.RELEASE</version>
</dependency>
在配置文件配置两个数据源。
spring:
datasource:
ds1:
url: jdbc:postgresql://ip:port/db1
username: username
password: password
driver-class-name: org.postgresql.Driver
ds2:
url: jdbc:postgresql://ip:port/db2
username: username
password: password
driver-class-name: org.postgresql.Driver
模仿 NutzDaoAutoConfiguration
实现一个自定义的 Configuration
@Configuration
public class NutzDaoConfiguration {
//主数据源配置 ds1数据源
@Primary
@Bean(name = "ds1DataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.ds1")
public DataSourceProperties ds1DataSourceProperties() {
return new DataSourceProperties();
}
//主数据源 ds1数据源
@Primary
@Bean(name = "ds1DataSource")
public DataSource ds1DataSource(@Qualifier("ds1DataSourceProperties") DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
//第二个ds2数据源配置
@Bean(name = "ds2DataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.ds2")
public DataSourceProperties ds2DataSourceProperties() {
return new DataSourceProperties();
}
//第二个ds2数据源
@Bean("ds2DataSource")
public DataSource ds2DataSource(@Qualifier("ds2DataSourceProperties") DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
@Bean(name = "dao1")
@Primary
@Autowired
public Dao primaryDao(@Qualifier("ds1DataSource") DataSource primaryDataSource, SqlManager sqlManager, DaoRunner daoRunner) {
NutDao dao = new NutDao(primaryDataSource, sqlManager);
dao.setRunner(daoRunner);
return dao;
}
@Bean(name = "dao2")
@Autowired
public Dao secondDao(@Qualifier("ds2DataSource") DataSource secondaryDataSource, SqlManager sqlManager, DaoRunner daoRunner) {
NutDao dao = new NutDao(secondaryDataSource, sqlManager);
dao.setRunner(daoRunner);
return dao;
}
}
到这基本就实现了双数据源的配置,但是在启动项目的时候会提示
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.nutz.spring.boot.dao.NutzDatabaseInitializer': Invocation of init method failed; nested exception is java.lang.NullPointerException
我猜测可能是 nutz-spring-boot-starter 中默认的 dao 没有东西注入。思考了一下干脆将主 dao 交由 nutz-spring-boot-starter 托管。
在配置文件中加入主 dao 的配置
nutz:
dao:
runtime:
create: true
basepackage:
- com.springbootdemo.entity.db1
自定义的 NutzDaoConfiguration
中,修改 ds1 数据源,并删除 dao1 的代码,最终代码如下
@Configuration
public class NutzDaoConfiguration {
//主数据源配置 ds1数据源
@Primary
@Bean(name = "ds1DataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.ds1")
public DataSourceProperties ds1DataSourceProperties() {
return new DataSourceProperties();
}
//主数据源 ds1数据源
@Primary
@Bean(name = "dataSource")
public DataSource dataSource(@Qualifier("ds1DataSourceProperties") DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
//第二个ds2数据源配置
@Bean(name = "ds2DataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.ds2")
public DataSourceProperties ds2DataSourceProperties() {
return new DataSourceProperties();
}
//第二个ds2数据源
@Bean("ds2DataSource")
public DataSource ds2DataSource(@Qualifier("ds2DataSourceProperties") DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
@Bean(name = "dao2")
@Autowired
public Dao secondDao(@Qualifier("ds2DataSource") DataSource secondaryDataSource, SqlManager sqlManager, DaoRunner daoRunner) {
NutDao dao = new NutDao(secondaryDataSource, sqlManager);
dao.setRunner(daoRunner);
return dao;
}
}
如此一来就可以使用多数据源了。
@Service
public class UserServiceImpl extends IdBaseService<User> implements UserService {
@Resource
Dao dao;
@Resource
Dao dao2;
@Override
public void getAllUsers() {
List<User> userList = dao().query(User.class, null); // nutz-spring-boot-starter 提供的 dao()
List<User> user1List = dao.query(User.class, null); // 自定义主 dao
List<User2> user2List = dao2.query(User2.class, null);
}
}
这样配置后主数据库中的实体会自动建表,其他数据库不会自动建表。这一块就自己实现 CommandLineRunner
进行创建即可。
解决问题的过程得到了许多人的帮助(特别是 @Kerbores 大佬),参考了许多文档,无法一一列出,感激之情留在心中。
才疏学浅,请各位大佬多多指点。