springboot框架 mybatis整合多数据源配置

背景:

     最近在学习当中,学到了多数据源的配置,在网上找了很多的资料一边配置,一边踩坑,也一边在学习,以此记录一下吧。

参考:

 本文参考了几个文章,但是或多多少都有些问题,所以我自己整合了下。链接放出

https://blog.csdn.net/maoyeqiu/article/details/74011626

https://blog.csdn.net/mxw2552261/article/details/78640062

出现的问题:

https://my.oschina.net/chinesedragon/blog/1647846

前期准备:

 springboot 2.0, mybatis,工具类:SqlSessionFactory 和 SqlSessionTemplate

 

多数据源:

 首先将我的配置贴出来(声明一下,我这里用的yml格式)

spring:
  ###主数据源
  primary:
    datasource:
      name: test1
      jdbc-url: jdbc:mysql://localhost:3306/test1?characterEncoding=utf8&useSSL=true
      username: root
      password: root
      type: com.alibaba.druid.pool.DruidDataSource

  ###第二数据源
  secondary:
    datasource:
      name: test2
      jdbc-url: jdbc:mysql://localhost:3306/test2?characterEncoding=utf8&useSSL=true
      username: root
      password: root
      type: com.alibaba.druid.pool.DruidDataSource

 我在这里配置了两个数据源,如果有多个,以此类推往下配置即可,我用的是mysql。

坑1

   这里有一点说一下,如果配置单数据源应该是 spring.datasource.name,这里因为配置多个应该按照spring.yourname.datasource.name,差别是在datasource前边加了一个自定义的名字,这样来区分多个数据源,而且如果不加的话会在编译的时候报错 配置文件内duplicate datasource。

坑2

   这里在配置数据库连接的时候一般单源或者springboot1.x版本都用的是 url:xxxxxxxx,而现在这种情况,多个源而且我的版本是2.0的所以应该写成jdbc-url: xxxxx,具体是因为版本还是多个数据源的原因只能去问大神了。

 数据源配置好了以后,在springboot内启动时会自动加载数据源的配置,这时候会出错,所以我们在你的启动类application.java内的注解添加一个属性。

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableTransactionManagement
public class JisusearchApplication {


   public static void main(String[] args) {
      SpringApplication.run(JisusearchApplication.class, args);
   }
}

  就是在 启动注解这里SpringBootApplication 添加了exclude属性。这里是防止springboot自动创建datasource,而忽略我们的配置。

新建datasource:

  我们禁掉了springboot默认创建的datasource,接下来我们就自己来创建我们需要的多个datasource。

  1、新建一个类,来配置datasource

@Configuration
public class DataSourceConfig {

    /**
     * 主数据源
     * @return
     */
    @Bean(name = "primaryDataSource")
//    @Qualifier("primaryDataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.primary.datasource")
    public DataSource primary() {
        return DataSourceBuilder.create().build();
    }

    /**
     * 从数据源
     * @return
     */
    @Bean(name = "secondaryDataSource")
//    @Qualifier("secondaryDataSource")
    @ConfigurationProperties(prefix = "spring.secondary.datasource")
    public DataSource secondary() {
        return DataSourceBuilder.create().build();
    }


}

首先  @Configuration 指定该类为spring的配置类相当于xml,

然后配置你在你的properties或yml文件内配置的数据源信息

@ConfigurationProperties(prefix = "spring.secondary.datasource")

这个注解会去properties文件内找你指定的前缀为spring.secondary.datasource的配置,因此这个值要跟你配置文件内些的一致。

名字你当然可以自定义了,我这个可能会有些长。

   注意

这里需要注意的是 我注释掉的注解@Qulifier 就是为该类指定名字的,因为我用了注解bean所以不能重复指定,不然会报错,还有就是这里可以指定一个默认的数据源 @Primary(指定默认数据源),网上也有人说没有必要,但是我这里不指定会报错。

这个坑请知道的大神 指点一下。

2、接下来使用工具类SqlSessionFactory和 SqlSessionTemplate 来完善你的配置

我的是分开创建的,即你有几个数据源就创建几个配置类,当然你先创建的多,也可以将这一步与上一步整合到一个类当中,看个人需要了。

上代码:

@Configuration
@MapperScan(basePackages = {"com.example.jisusearch.primarydao"}, sqlSessionFactoryRef = "primarySqlSessionFactory")
public class MybatisPrimaryConfig {

    @Autowired
    @Qualifier("primaryDataSource")
    private DataSource primaryDataSource;

    @Bean
    public SqlSessionFactory primarySqlSessionFactory () throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(primaryDataSource);
        return bean.getObject();
    }

    @Bean
    public SqlSessionTemplate primarySqlSessionTemplate() throws Exception {
        SqlSessionTemplate template = new SqlSessionTemplate(primarySqlSessionFactory());
        return template;
    }
}

这里引入上一步配置的datasource,并通过注解@Qualifier 来指定你目前这个SqlSessionFactory使用的是哪个数据源,类上加上注解@Configuration 声明该类为配置类;

@MapperScan(basePackages = {"com.example.jisusearch.primarydao"}, sqlSessionFactoryRef = "primarySqlSessionFactory")

该注解来指定你哪个包要使用这个数据源,要写全路径,不然会报错,后边这个属性则是你SqlSessionFactory的bean的名字。

这里是一个数据源的配置,接下来配置另外一个,类似就直接上代码了。

@Configuration
@MapperScan(basePackages = {"com.example.jisusearch.secondarydao"}, sqlSessionFactoryRef = "secondarySqlSessionFactory")
public class MybatisSecondaryConfig {

    @Autowired
    @Qualifier("secondaryDataSource")
    private DataSource secondaryDataSource;

    @Bean
    public SqlSessionFactory secondarySqlSessionFactory() throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(secondaryDataSource);
        return bean.getObject();
    }

    @Bean
    public SqlSessionTemplate secondarySqlSessionTemplate() throws Exception {
        SqlSessionTemplate template = new SqlSessionTemplate(secondarySqlSessionFactory());
        return template;
    }
}

因为我想要分开所以我建了两个dao,你也可以在一个dao内指定这两个,但是@MapperScan(basePackages = {"com.example.jisusearch.secondarydao"}) 这里就不能写到包了,路径应该写到你指定的mapper上,xml或者java类,例如:com.example.jisusearch.secondarydao.UserDao,多个的话用逗号分开就可以了。

3、新建dao

@Mapper
public interface PrimaryDao {

    @SelectProvider(type = PrimaryProviders.class, method = "getUserSql")
    @Results(id = "systemUser", value = {
            @Result(property = "userId", column = "user_id"),
            @Result(property = "username", column = "username"),
            @Result(property = "createUserId", column = "create_user_id"),
            @Result(property = "createTime", column = "create_time"),
    })
    UserModule getUser (String id);

    @ResultMap("systemUser")
    @SelectProvider(type = PrimaryProviders.class, method = "getUserByParamsSql")
    UserModule getUserByParams (String id);

}

   

扩展一下:我这里做了字段的映射使用的是 @Results和@Result,因为这两个都是方法级的注解,所以为了能共用我为@Results加了id的属性,其他的地方引用使用@ResultMap("yourResultId"),有人说这样不可以,但是本人亲测可用。

另外一个dao包下的方法

@Mapper
public interface SecondaryDao {

    @SelectProvider(type = SecondaryProviders.class, method = "getUserSql")
    @Results(id = "systemUser", value = {
            @Result(property = "userId", column = "user_id"),
            @Result(property = "username", column = "username"),
            @Result(property = "createUserId", column = "create_user_id"),
            @Result(property = "createTime", column = "create_time"),
    })
    UserModule getUser(@Param("id") String id);


}

  这里sql语句我都是用java写的,dao层用的注解@SelectProvider,因为本人实在不喜欢写xml -_-!!!。

4、写你的test类或者使用三层,将到dao正常的注入到你的service或controller内,就可以正常使用了。

    @Resource
    private PrimaryDao primaryDao;
    @Resource
    private SecondaryDao secondaryDao;

    @RequestMapping("/primary/user")
    public Result findUser(String id) {
        Result re = new Result();
        Map<String, Object> map = new HashMap<>();
        UserModule userModule = primaryDao.getUser(id);
        UserModule userModule1 = secondaryDao.getUser(id);
        UserModule userModule2 = primaryDao.getUserByParams(id);
        map.put("first", userModule);
        map.put("second", userModule1);
        map.put("third", userModule2);
        re.setData(map);
        return re;
    }

  这里有个坑,就是注入你的dao时不能使用autowired,因为会报错,你现在多个数据源而不是单个了

好了, 我的配置到此就结束了,代码直接copy可用。

猜你喜欢

转载自blog.csdn.net/Mars_wen/article/details/81116430