300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Spring Boot 2.x基础教程:MyBatis的多数据源配置

Spring Boot 2.x基础教程:MyBatis的多数据源配置

时间:2020-04-04 23:08:10

相关推荐

Spring Boot 2.x基础教程:MyBatis的多数据源配置

点击上方蓝色“程序猿DD”,选择“设为星标”

回复“资源”获取独家整理的学习资料!

前两天,我们已经介绍了关于JdbcTemplate的多数据源配置以及Spring Data JPA的多数据源配置,接下来具体说说使用MyBatis时候的多数据源场景该如何配置。

添加多数据源的配置

先在Spring Boot的配置文件application.properties中设置两个你要链接的数据库配置,比如这样:

spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1spring.datasource.primary.username=rootspring.datasource.primary.password=123456spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2spring.datasource.secondary.username=rootspring.datasource.secondary.password=123456spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver

说明与注意

多数据源配置的时候,与单数据源不同点在于spring.datasource之后多设置一个数据源名称primary和secondary来区分不同的数据源配置,这个前缀将在后续初始化数据源的时候用到。

数据源连接配置2.x和1.x的配置项是有区别的:2.x使用spring.datasource.secondary.jdbc-url,而1.x版本使用spring.datasource.secondary.url。如果你在配置的时候发生了这个报错java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.,那么就是这个配置项的问题。

可以看到,不论使用哪一种数据访问框架,对于数据源的配置都是一样的。

初始化数据源与MyBatis配置

完成多数据源的配置信息之后,就来创建个配置类来加载这些配置信息,初始化数据源,以及初始化每个数据源要用的MyBatis配置。

这里我们继续将数据源与框架配置做拆分处理:

单独建一个多数据源的配置类,比如下面这样:

@ConfigurationpublicclassDataSourceConfiguration{@Primary@Bean@ConfigurationProperties(prefix="spring.datasource.primary")publicDataSourceprimaryDataSource(){returnDataSourceBuilder.create().build();}@Bean@ConfigurationProperties(prefix="spring.datasource.secondary")publicDataSourcesecondaryDataSource(){returnDataSourceBuilder.create().build();}}

可以看到内容跟JdbcTemplate、Spring Data JPA的时候是一模一样的。通过@ConfigurationProperties可以知道这两个数据源分别加载了spring.datasource.primary.*spring.datasource.secondary.*的配置。@Primary注解指定了主数据源,就是当我们不特别指定哪个数据源的时候,就会使用这个Bean真正差异部分在下面的JPA配置上。

分别创建两个数据源的MyBatis配置。

Primary数据源的JPA配置:

@Configuration@MapperScan(basePackages="com.didispace.chapter39.p",sqlSessionFactoryRef="sqlSessionFactoryPrimary",sqlSessionTemplateRef="sqlSessionTemplatePrimary")publicclassPrimaryConfig{privateDataSourceprimaryDataSource;publicPrimaryConfig(@Qualifier("primaryDataSource")DataSourceprimaryDataSource){this.primaryDataSource=primaryDataSource;}@BeanpublicSqlSessionFactorysqlSessionFactoryPrimary()throwsException{SqlSessionFactoryBeanbean=newSqlSessionFactoryBean();bean.setDataSource(primaryDataSource);returnbean.getObject();}@BeanpublicSqlSessionTemplatesqlSessionTemplatePrimary()throwsException{returnnewSqlSessionTemplate(sqlSessionFactoryPrimary());}}

Secondary数据源的JPA配置:

@Configuration@MapperScan(basePackages="com.didispace.chapter39.s",sqlSessionFactoryRef="sqlSessionFactorySecondary",sqlSessionTemplateRef="sqlSessionTemplateSecondary")publicclassSecondaryConfig{privateDataSourcesecondaryDataSource;publicSecondaryConfig(@Qualifier("secondaryDataSource")DataSourcesecondaryDataSource){this.secondaryDataSource=secondaryDataSource;}@BeanpublicSqlSessionFactorysqlSessionFactorySecondary()throwsException{SqlSessionFactoryBeanbean=newSqlSessionFactoryBean();bean.setDataSource(secondaryDataSource);returnbean.getObject();}@BeanpublicSqlSessionTemplatesqlSessionTemplateSecondary()throwsException{returnnewSqlSessionTemplate(sqlSessionFactorySecondary());}}

说明与注意

配置类上使用@MapperScan注解来指定当前数据源下定义的Entity和Mapper的包路径;另外需要指定sqlSessionFactory和sqlSessionTemplate,这两个具体实现在该配置类中类中初始化。

配置类的构造函数中,通过@Qualifier注解来指定具体要用哪个数据源,其名字对应在DataSourceConfiguration配置类中的数据源定义的函数名。

配置类中定义SqlSessionFactory和SqlSessionTemplate的实现,注意具体使用的数据源正确(如果使用这里的演示代码,只要第二步没问题就不需要修改)。

上一篇介绍JPA的时候,因为之前介绍JPA的使用时候,说过实体和Repository定义的方法,所以省略了 User 和 Repository的定义代码,但是还是有读者问怎么没有这个,其实都有说明,仓库代码里也都是有的。未避免再问这样的问题,所以这里就贴一下吧。

根据上面Primary数据源的定义,在com.didispace.chapter39.p包下,定义Primary数据源要用的实体和数据访问对象,比如下面这样:

@Data@NoArgsConstructorpublicclassUserPrimary{privateLongid;privateStringname;privateIntegerage;publicUserPrimary(Stringname,Integerage){this.name=name;this.age=age;}}publicinterfaceUserMapperPrimary{@Select("SELECT*FROMUSERWHERENAME=#{name}")UserPrimaryfindByName(@Param("name")Stringname);@Insert("INSERTINTOUSER(NAME,AGE)VALUES(#{name},#{age})")intinsert(@Param("name")Stringname,@Param("age")Integerage);@Delete("DELETEFROMUSER")intdeleteAll();}

根据上面Secondary数据源的定义,在com.didispace.chapter39.s包下,定义Secondary数据源要用的实体和数据访问对象,比如下面这样:

@Data@NoArgsConstructorpublicclassUserSecondary{privateLongid;privateStringname;privateIntegerage;publicUserSecondary(Stringname,Integerage){this.name=name;this.age=age;}}publicinterfaceUserMapperSecondary{@Select("SELECT*FROMUSERWHERENAME=#{name}")UserSecondaryfindByName(@Param("name")Stringname);@Insert("INSERTINTOUSER(NAME,AGE)VALUES(#{name},#{age})")intinsert(@Param("name")Stringname,@Param("age")Integerage);@Delete("DELETEFROMUSER")intdeleteAll();}

测试验证

完成了上面之后,我们就可以写个测试类来尝试一下上面的多数据源配置是否正确了,先来设计一下验证思路:

往Primary数据源插入一条数据

从Primary数据源查询刚才插入的数据,配置正确就可以查询到

从Secondary数据源查询刚才插入的数据,配置正确应该是查询不到的

往Secondary数据源插入一条数据

从Primary数据源查询刚才插入的数据,配置正确应该是查询不到的

从Secondary数据源查询刚才插入的数据,配置正确就可以查询到

具体实现如下:

@Slf4j@RunWith(SpringRunner.class)@SpringBootTest@TransactionalpublicclassChapter39ApplicationTests{@AutowiredprivateUserMapperPrimaryuserMapperPrimary;@AutowiredprivateUserMapperSecondaryuserMapperSecondary;@BeforepublicvoidsetUp(){//清空测试表,保证每次结果一样userMapperPrimary.deleteAll();userMapperSecondary.deleteAll();}@Testpublicvoidtest()throwsException{//往Primary数据源插入一条数据userMapperPrimary.insert("AAA",20);//从Primary数据源查询刚才插入的数据,配置正确就可以查询到UserPrimaryuserPrimary=userMapperPrimary.findByName("AAA");Assert.assertEquals(20,userPrimary.getAge().intValue());//从Secondary数据源查询刚才插入的数据,配置正确应该是查询不到的UserSecondaryuserSecondary=userMapperSecondary.findByName("AAA");Assert.assertNull(userSecondary);//往Secondary数据源插入一条数据userMapperSecondary.insert("BBB",20);//从Primary数据源查询刚才插入的数据,配置正确应该是查询不到的userPrimary=userMapperPrimary.findByName("BBB");Assert.assertNull(userPrimary);//从Secondary数据源查询刚才插入的数据,配置正确就可以查询到userSecondary=userMapperSecondary.findByName("BBB");Assert.assertEquals(20,userSecondary.getAge().intValue());}}

代码示例

本文的相关例子可以查看下面仓库中的chapter3-9目录:

Github:/dyc87112/SpringBoot-Learning/

Gitee:/didispace/SpringBoot-Learning/

如果您觉得本文不错,欢迎Star支持,您的关注是我坚持的动力!

往期推荐

Dubbo 高危反序列化漏洞,存在远程代码执行风险,建议及时升级到2.7.7或更高版本!

如何实现一个可复用的分布式事务消息架构方案?

Spring Boot 2.x基础教程:Spring Data JPA的多数据源配置

API 面试四连杀:接口如何设计?安全如何保证?签名如何实现?防重如何实现?

开源|阿里巴巴的国产JDK Dragonwell:龙井

RabbitMQ 的这些骚操作你知道吗?

欢迎加入我的知识星球,聊技术、说职场、侃社会。

头发很多的中年程序员DD和他的朋友们在这里期待你的到来!

加入方式:长按下方二维码噢

近期预告

【技术圈】分享最近给阿里提的一个数据安全问题

【聊职场】说说公司股权与期权的那些门道

最近更新:

【技术圈】分享最近碰到的API网关的奇怪用法...

【社会人】社会入门最不能忽略的五险一金

我的星球是否适合你?

点击阅读原文看看我们都聊过啥?

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。