Springboot 配置多数据源

多数据源:
 首先将我的配置贴出来(声明一下,我这里用的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可用。
--------------------- 
作者:Mars_wen 
来源:CSDN 
原文:https://blog.csdn.net/Mars_wen/article/details/81116430 
版权声明:本文为博主原创文章,转载请附上博文链接!

  

转载于:https://www.cnblogs.com/leigepython/p/10457358.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值