NutzCN Logo
精华 SpringBoot 整合 nutz-spring-boot-starter 配置多数据源
发布于 55天前 作者 KerwinChen 181 次浏览 复制 上一个帖子 下一个帖子
标签:

直入主题,先引入 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 大佬),参考了许多文档,无法一一列出,感激之情留在心中。
才疏学浅,请各位大佬多多指点。

1 回复

你好,请问这块的连接池你是怎么做配置的

添加回复
请先登陆
回到顶部