MyBatis多数据源的两种配置方式
前言
同一个项目有时会涉及到多个数据库,也就是多数据源。多数据源又可以分为两种情况:
1)两个或多个数据库没有相关性,各自独立,其实这种可以作为两个项目来开发。比如在游戏开发中一个数据库是平台数据库,其它还有平台下的游戏对应的数据库;
2)两个或多个数据库是master-slave的关系,比如有mysql搭建一个master-master,其后又带有多个slave;或者采用MHA搭建的master-slave复制;
MyBatis多数据源的配置主要有两种方式:
- 通过@MapperScan注解,对不同包下的Mapper使用不同的sqlSessionFactory
- 通过@MapperScan注解加自定义注解,对使用不同注解的Mapper使用不同的sqlSessionFactory
第二种配置相对灵活,示例如下:
packagebj; importch.qos.logback.classic.Level; importch.qos.logback.classic.Logger; importcom.zaxxer.hikari.HikariDataSource; importio.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration; importorg.apache.ibatis.annotations.Mapper; importorg.apache.ibatis.annotations.Select; importorg.apache.ibatis.session.SqlSessionFactory; importorg.mybatis.spring.SqlSessionFactoryBean; importorg.mybatis.spring.annotation.MapperScan; importorg.slf4j.LoggerFactory; importorg.springframework.boot.SpringApplication; importorg.springframework.boot.WebApplicationType; importorg.springframework.boot.autoconfigure.SpringBootApplication; importorg.springframework.boot.context.event.ApplicationReadyEvent; importorg.springframework.context.ApplicationListener; importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration; importorg.springframework.context.annotation.Primary; importorg.springframework.jdbc.core.JdbcTemplate; importjavax.annotation.Resource; importjavax.sql.DataSource; importjava.lang.annotation.ElementType; importjava.lang.annotation.Retention; importjava.lang.annotation.RetentionPolicy; importjava.lang.annotation.Target; importjava.util.List; importjava.util.Map; /** *CreatedbyBaiJiFeiLong@gmail.comat2018/12/6下午9:29 **MyBatis多数据源演示 */ @SpringBootApplication(exclude={SpringBootConfiguration.class}) @Configuration @MapperScan(annotationClass=Mapper.class,basePackageClasses=MyBatisApp.class, sqlSessionFactoryRef="sqlSessionFactory") publicclassMyBatisAppimplementsApplicationListener
{ /** *SecondaryMapper配置 *\@MapperScan注解一次只能添加一个,所以需要单独再加一个配置类 *自定义@MapperScan会替换MyBatis自动添加的默认@MapperScan。所以主@MapperScan也必须显式添加 */ @Configuration @MapperScan(annotationClass=SecondaryMapper.class,basePackageClasses=MyBatisApp.class, sqlSessionFactoryRef="sqlSessionFactorySecond") staticclassSecondaryMapperConfiguration{ } publicstaticvoidmain(String[]args){ newSpringApplication(MyBatisApp.class){{ setWebApplicationType(WebApplicationType.NONE); }}.run(args); } @Resource privateDataSourcedataSource; @Resource privateDataSourcedataSourceSecond; @Resource privateJdbcTemplatejdbcTemplate; @Resource privateUserMapperuserMapper; @Resource privateSecondaryUserMappersecondaryUserMapper; privatevoidinitLogger(){ ((Logger)LoggerFactory.getLogger(MyBatisApp.class)).setLevel(Level.DEBUG); ((Logger)LoggerFactory.getLogger(JdbcTemplate.class)).setLevel(Level.DEBUG); } privatevoidinitDatabase(){ StringoldDatabase=jdbcTemplate.queryForObject("SELECTDATABASE()",String.class); jdbcTemplate.execute("DROPSCHEMAIFEXISTSone"); jdbcTemplate.execute("CREATESCHEMAone"); jdbcTemplate.execute("USEone"); jdbcTemplate.execute("CREATETABLEuser(idINTAUTO_INCREMENTPRIMARYKEY,nameVARCHAR(32)CHARSET'utf8')"); jdbcTemplate.execute("INSERTINTOuser(name)VALUES('人民的儿子')"); jdbcTemplate.execute("INSERTINTOuser(name)VALUES('人民的孙子')"); jdbcTemplate.execute("INSERTINTOuser(name)VALUES('人民的曾孙子')"); jdbcTemplate.execute("DROPSCHEMAIFEXISTStwo"); jdbcTemplate.execute("CREATESCHEMAtwo"); jdbcTemplate.execute("USEtwo"); jdbcTemplate.execute("CREATETABLEuser(idINTAUTO_INCREMENTPRIMARYKEY,nameVARCHAR(32)CHARSET'utf8')"); jdbcTemplate.execute("INSERTINTOuser(name)VALUES('人民的爹')"); jdbcTemplate.execute("INSERTINTOuser(name)VALUES('人民的爷')"); jdbcTemplate.execute("INSERTINTOuser(name)VALUES('人民的太爷')"); jdbcTemplate.execute("INSERTINTOuser(name)VALUES('人民的老太爷')"); jdbcTemplate.execute("USE"+oldDatabase); } @Override publicvoidonApplicationEvent(ApplicationReadyEventapplicationReadyEvent){ initLogger(); initDatabase(); System.out.println("Users:"); userMapper.selectAll().forEach(System.out::println); System.out.println("Secondaryusers:"); secondaryUserMapper.selectAll().forEach(System.out::println); } /** *主数据源 * *如果不添加@Primary注解,MyBatis可以工作,但是JdbcTemplate无法注入 * *@return. */ @Primary @Bean publicDataSourcedataSource(){ returnnewHikariDataSource(){{ setJdbcUrl("jdbc:mysql://localhost/one?useUnicode=true&characterEncoding=utf8"); setUsername("root"); setPassword("root"); }}; } /** *副数据源 * *@return. */ @Bean publicDataSourcedataSourceSecond(){ returnnewHikariDataSource(){{ setJdbcUrl("jdbc:mysql://localhost/two?useUnicode=true&characterEncoding=utf8"); setUsername("root"); setPassword("root"); }}; } /** *主SqlSessionFactory。使用主数据源。自定义SqlSessionFactory后,MyBatis就不自动添加SqlSessionFactory了,所以必须有 * *@return. *@throwsException. */ @Bean publicSqlSessionFactorysqlSessionFactory()throwsException{ returnnewSqlSessionFactoryBean(){{ setDataSource(dataSource); }}.getObject(); } /** *副SqlSessionFactory。使用副数据源 * *@return. *@throwsException. */ @Bean publicSqlSessionFactorysqlSessionFactorySecond()throwsException{ returnnewSqlSessionFactoryBean(){{ setDataSource(dataSourceSecond); }}.getObject(); } @Mapper interfaceUserMapper{ @Select("SELECT*FROMuser") List
控制台输出:
. ____ _ ____
/\\/___'_____(_)___ ___\\\\
(()\___|'_|'_||'_\/_`|\\\\
\\/ ___)||_)|||||||(_|| ))))
' |____|.__|_||_|_||_\__,|////
=========|_|==============|___/=/_/_/_/
::SpringBoot:: (v2.1.0.RELEASE)2018-12-0711:49:02.596 INFO5154---[ main]bj.MyBatisApp :StartingMyBatisApponMacBook-Air-2.localwithPID5154(/Users/yuchao/temp/java/hellomaven/target/classesstartedbyyuchaoin/Users/yuchao/temp/java/hellomaven)
2018-12-0711:49:02.633 INFO5154---[ main]bj.MyBatisApp :Noactiveprofileset,fallingbacktodefaultprofiles:default
2018-12-0711:49:05.341 INFO5154---[ main]com.zaxxer.hikari.HikariDataSource :HikariPool-1-Starting...
2018-12-0711:49:05.499 INFO5154---[ main]com.zaxxer.hikari.HikariDataSource :HikariPool-1-Startcompleted.
2018-12-0711:49:05.547 INFO5154---[ main]org.quartz.impl.StdSchedulerFactory :UsingdefaultimplementationforThreadExecutor
2018-12-0711:49:05.569 INFO5154---[ main]org.quartz.core.SchedulerSignalerImpl :InitializedSchedulerSignalleroftype:classorg.quartz.core.SchedulerSignalerImpl
2018-12-0711:49:05.569 INFO5154---[ main]org.quartz.core.QuartzScheduler :QuartzSchedulerv.2.3.0created.
2018-12-0711:49:05.570 INFO5154---[ main]org.quartz.simpl.RAMJobStore :RAMJobStoreinitialized.
2018-12-0711:49:05.571 INFO5154---[ main]org.quartz.core.QuartzScheduler :Schedulermeta-data:QuartzScheduler(v2.3.0)'quartzScheduler'withinstanceId'NON_CLUSTERED'
Schedulerclass:'org.quartz.core.QuartzScheduler'-runninglocally.
NOTSTARTED.
Currentlyinstandbymode.
Numberofjobsexecuted:0
Usingthreadpool'org.quartz.simpl.SimpleThreadPool'-with10threads.
Usingjob-store'org.quartz.simpl.RAMJobStore'-whichdoesnotsupportpersistence.andisnotclustered.2018-12-0711:49:05.571 INFO5154---[ main]org.quartz.impl.StdSchedulerFactory :Quartzscheduler'quartzScheduler'initializedfromanexternallyprovidedpropertiesinstance.
2018-12-0711:49:05.571 INFO5154---[ main]org.quartz.impl.StdSchedulerFactory :Quartzschedulerversion:2.3.0
2018-12-0711:49:05.571 INFO5154---[ main]org.quartz.core.QuartzScheduler :JobFactorysetto:org.springframework.scheduling.quartz.SpringBeanJobFactory@769a58e5
2018-12-0711:49:05.780 WARN5154---[ main]reactor.netty.tcp.TcpResources :[http]resourceswillusethedefaultLoopResources:DefaultLoopResources{prefix=reactor-http,daemon=true,selectCount=4,workerCount=4}
2018-12-0711:49:05.780 WARN5154---[ main]reactor.netty.tcp.TcpResources :[http]resourceswillusethedefaultConnectionProvider:PooledConnectionProvider{name=http,poolFactory=reactor.netty.resources.ConnectionProvider$$Lambda$284/1788545647@10667848}
2018-12-0711:49:06.061 INFO5154---[ main]o.s.s.quartz.SchedulerFactoryBean :StartingQuartzSchedulernow
2018-12-0711:49:06.062 INFO5154---[ main]org.quartz.core.QuartzScheduler :SchedulerquartzScheduler_$_NON_CLUSTEREDstarted.
2018-12-0711:49:06.079 INFO5154---[ main]bj.MyBatisApp :StartedMyBatisAppin4.645seconds(JVMrunningfor6.354)
2018-12-0711:49:06.084DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLquery[SELECTDATABASE()]
2018-12-0711:49:06.105DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[DROPSCHEMAIFEXISTSone]
2018-12-0711:49:06.115DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[CREATESCHEMAone]
2018-12-0711:49:06.117DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[USEone]
2018-12-0711:49:06.119DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[CREATETABLEuser(idINTAUTO_INCREMENTPRIMARYKEY,nameVARCHAR(32)CHARSET'utf8')]
2018-12-0711:49:06.153DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[INSERTINTOuser(name)VALUES('人民的儿子')]
2018-12-0711:49:06.157DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[INSERTINTOuser(name)VALUES('人民的孙子')]
2018-12-0711:49:06.161DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[INSERTINTOuser(name)VALUES('人民的曾孙子')]
2018-12-0711:49:06.164DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[DROPSCHEMAIFEXISTStwo]
2018-12-0711:49:06.174DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[CREATESCHEMAtwo]
2018-12-0711:49:06.176DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[USEtwo]
2018-12-0711:49:06.178DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[CREATETABLEuser(idINTAUTO_INCREMENTPRIMARYKEY,nameVARCHAR(32)CHARSET'utf8')]
2018-12-0711:49:06.226DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[INSERTINTOuser(name)VALUES('人民的爹')]
2018-12-0711:49:06.231DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[INSERTINTOuser(name)VALUES('人民的爷')]
2018-12-0711:49:06.235DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[INSERTINTOuser(name)VALUES('人民的太爷')]
2018-12-0711:49:06.243DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[INSERTINTOuser(name)VALUES('人民的老太爷')]
2018-12-0711:49:06.246DEBUG5154---[ main]o.s.jdbc.core.JdbcTemplate :ExecutingSQLstatement[USEone]
Users:
2018-12-0711:49:06.271DEBUG5154---[ main]bj.MyBatisApp$UserMapper.selectAll :==> Preparing:SELECT*FROMuser
2018-12-0711:49:06.297DEBUG5154---[ main]bj.MyBatisApp$UserMapper.selectAll :==>Parameters:
2018-12-0711:49:06.314DEBUG5154---[ main]bj.MyBatisApp$UserMapper.selectAll :<== Total:3
{name=人民的儿子,id=1}
{name=人民的孙子,id=2}
{name=人民的曾孙子,id=3}
Secondaryusers:
2018-12-0711:49:06.318 INFO5154---[ main]com.zaxxer.hikari.HikariDataSource :HikariPool-2-Starting...
2018-12-0711:49:06.324 INFO5154---[ main]com.zaxxer.hikari.HikariDataSource :HikariPool-2-Startcompleted.
2018-12-0711:49:06.325DEBUG5154---[ main]b.M.selectAll :==> Preparing:SELECT*FROMuser
2018-12-0711:49:06.325DEBUG5154---[ main]b.M.selectAll :==>Parameters:
2018-12-0711:49:06.328DEBUG5154---[ main]b.M.selectAll :<== Total:4
{name=人民的爹,id=1}
{name=人民的爷,id=2}
{name=人民的太爷,id=3}
{name=人民的老太爷,id=4}
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。