多数据源配置引入
mybatis和mysql在springboot中的引入这里就不在说了,不了解的可以参见springboot中mysql与mybatis的引入。
数据源配置如下:
datasource: master: type: com.alibaba.druid.pool.druiddatasource jdbc-url: jdbc:mysql://127.0.0.1:3306/sbac_master?autoreconnect=true&useunicode=true&characterencoding=utf-8&zerodatetimebehavior=converttonull&allowmultiqueries=true username: root password: 1234 driver-class-name: com.mysql.cj.jdbc.driver log: type: com.alibaba.druid.pool.druiddatasource jdbc-url: jdbc:mysql://127.0.0.1:3306/sbac_log?autoreconnect=true&useunicode=true&characterencoding=utf-8&zerodatetimebehavior=converttonull&allowmultiqueries=true username: root password: 1234 driver-class-name: com.mysql.cj.jdbc.driver
mybatis的配置引入如下:
mybatis: config-location: classpath:mybatis-config.xml mapper-locations: classpath:com/lazycece/sbac/mysql/data/dao/*/mapper/*.xml
这里已然使用的是springboot的自动配置功能配置mybatis信息,只是手动指定了数据源的。如下所示,指定了master和log两个数据源,设置master为默认数据源:
@configurationpublic class multidatasource { public static final string master_data_source = "masterdatasource"; public static final string log_data_source = "logdatasource"; @bean(name = multidatasource.master_data_source) @configurationproperties(prefix = "datasource.master") public datasource masterdatasource() { return datasourcebuilder.create().build(); } @bean(name = multidatasource.log_data_source) @configurationproperties(prefix = "datasource.log") public datasource logdatasource() { return datasourcebuilder.create().build(); } @primary @bean(name = "dynamicdatasource") public dynamicdatasource datasource() { dynamicdatasource dynamicdatasource = new dynamicdatasource(); dynamicdatasource.setdefaulttargetdatasource(masterdatasource()); map<object, object> datasourcemap = new hashmap<>(4); datasourcemap.put(master_data_source, masterdatasource()); datasourcemap.put(log_data_source, logdatasource()); dynamicdatasource.settargetdatasources(datasourcemap); return dynamicdatasource; }}
动态数据源路由实现
引入了配置信息之后,便是该说如何实现多数据源切换了。我们是通过实现abstractroutingdatasource类的determinecurrentlookupkey方法来实现数据源的动态路由,设置threadlocal线程保护变量存储数据源key,确保线程间不受影响。
package com.lazycece.sbac.mysql.multi.config;import org.slf4j.logger;import org.slf4j.loggerfactory;import org.springframework.jdbc.datasource.lookup.abstractroutingdatasource;/** * @author lazycece */public class dynamicdatasource extends abstractroutingdatasource { private static final logger logger = loggerfactory.getlogger(dynamicdatasource.class); private static final threadlocal<string> data_source_key = new threadlocal<>(); static void changedatasource(string datasourcekey) { data_source_key.set(datasourcekey); } static void cleardatasource() { data_source_key.remove(); } @override protected object determinecurrentlookupkey() { string key = data_source_key.get(); logger.info("current data-source is {}", key); return key; }}
随后,便是用aop的方式来实现数据源的动态切换,注解和切面定义如下:
@documented@inherited@retention(retentionpolicy.runtime)@target({elementtype.method, elementtype.type})public @interface datasource { string value();}@component@aspectpublic class datasourceconfig { @before("@annotation(datasource)") public void beforeswitchdatasource(datasource datasource) { dynamicdatasource.changedatasource(datasource.value()); } @after("@annotation(datasource)") public void afterswitchdatasource() { dynamicdatasource.cleardatasource(); }}
动态数据源切换使用
动态数据源切换只需要在业务中使用@datasource注解来标明需要使用的数据源即可,如下所示(这里只贴出关键代码):
@servicepublic class dynamicdatasourceserviceimpl implements dynamicdatasourceservice { @resource private userdao userdao; @resource private systemlogdao systemlogdao; @override @datasource(value = multidatasource.master_data_source) public void adduserinfo(user user) { userdao.insert(user); } @override @datasource(value = multidatasource.master_data_source) public user getuserinfo(string username) { return userdao.findbyusername(username); } @override @datasource(value = multidatasource.log_data_source) public void addsystemlog(systemlog systemlog) { systemlogdao.insert(systemlog); } @override @datasource(value = multidatasource.log_data_source) public list<systemlog> getsystemloginfo(date begintime, date endtime) { return systemlogdao.findbycreatetime(begintime, endtime); }}
以上就是springboot中怎么实现mybatis多数据源动态切换的详细内容。