springBoot 動態資料來源以及Mybatis多資料來源
原文地址:https://blog.csdn.net/tengxing007/article/details/78424645
前言
在開發過程中可能需要用到多個數據源,比如一個專案(MySQL)就是和(SQL Server)混合使用,就需要使用多資料來源;如果業務場景比較復炸,可以使用動態資料來源,靈活切換,典型的應用就是讀寫分離。下面分兩個模組來配置資料來源,大家可以根據自己實際情況配置。
多資料來源
禁用DataSourceAutoConfiguration
如果DataSourceAutoConfiguration不禁用的話,就會報錯,多個數據源,無法裝配哪一個。在springBoot的主程式入口的註解
@SpringBootApplication (exclude = {
DataSourceAutoConfiguration.class
})
- 配置application.properties
#datasource 這是自動裝配的預設配置禁止,這裡不能使用
#spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#spring.datasource.url=jdbc:mysql://127.0.0.1:3306/api_resources?#autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
#spring.datasource.username=api
#spring.datasource.password=api
#db1
spring.datasource.db1.url=jdbc:mysql://127.0.0.1:3306/api_resources?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
spring.datasource.db1.username=api
spring.datasource.db1.password=api
spring.datasource .db1.driver-class-name=com.mysql.jdbc.Driver
#db2
spring.datasource.db2.url=jdbc:mysql://127.0.0.1:3306/ssm?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
spring.datasource.db2.username=api
spring.datasource.db2.password=api
spring.datasource.db2.driver-class-name=com.mysql.jdbc.Driver
配置dataSource
配置兩個資料來源,分別為db1,和db2
/**
* Author: Starry.Teng
* Email: [email protected]
* Date: 17-11-1
* Time: 下午9:14
* Describe: DataSource Config
*/
@Configuration
public class DataSourceConfig {
@Autowired
Environment env;
@Bean(name = "ds1")
public DataSource dataSource1() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(env.getProperty("spring.datasource.db1.url"));
dataSource.setUsername(env.getProperty("spring.datasource.db1.username"));
dataSource.setPassword(env.getProperty("spring.datasource.db1.password"));
dataSource.setDriverClassName(env.getProperty("spring.datasource.db1.driver-class-name"));
return dataSource;
}
@Bean(name = "ds2")
public DataSource dataSource2() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(env.getProperty("spring.datasource.db2.url"));
dataSource.setUsername(env.getProperty("spring.datasource.db2.username"));
dataSource.setPassword(env.getProperty("spring.datasource.db2.password"));
dataSource.setDriverClassName(env.getProperty("spring.datasource.db2.driver-class-name"));
return dataSource;
}
}
Mybatis配置
為兩個資料來源分貝配置一個MybatisDb1Config類和MybatisDb2Config類,對資料來源進行管理,注意他們所管理的包是不同的。
/**
* Author: Starry.Teng
* Email: [email protected]
* Date: 17-11-1
* Time: 下午9:15
* Describe: MybatisDb1 Config
*/
@Configuration
@MapperScan(basePackages = {"cn.yjxxclub.demo.datasource.dao.db1"}, sqlSessionFactoryRef = "sqlSessionFactory1")
public class MybatisDb1Config {
@Qualifier("ds1")
@Autowired
DataSource dataSource;
@Bean(name = "sqlSessionFactory1")
public SqlSessionFactory sqlSessionFactory1() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
factoryBean.setMapperLocations(resolver.getResources("classpath:mappers/db1/*.xml"));
factoryBean.setTypeAliasesPackage("cn.yjxxclub.demo.datasource.model");
return factoryBean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate1() throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory1()); // 使用上面配置的Factory
return template;
}
}
/**
* Author: Starry.Teng
* Email: [email protected]
* Date: 17-11-1
* Time: 下午9:26
* Describe: MybatisDb2 Config
*/
@Configuration
@MapperScan(basePackages = {"cn.yjxxclub.demo.datasource.dao.db2"}, sqlSessionFactoryRef = "sqlSessionFactory2")
public class MybatisDb2Config {
@Qualifier("ds2")
@Autowired
DataSource dataSource;
@Bean(name = "sqlSessionFactory2")
public SqlSessionFactory sqlSessionFactory2() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
factoryBean.setMapperLocations(resolver.getResources("classpath:mappers/db2/*.xml"));
factoryBean.setTypeAliasesPackage("cn.yjxxclub.demo.datasource.model");
return factoryBean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate2() throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory2());
return template;
}
}
編寫Dao和Mapper
Mapper.java和mapper.xml在basePackages和classpath對應放置即可,和springboot整合Mybtis一樣,這裡就不說了,然後正常啟動即可。程式碼在此:https://github.com/tengxing/Multiple-dataSources
資料來源動態切換
資料來源註冊
/**
* Author: Starry.Teng
* Email: [email protected]
* Date: 17-11-1
* Time: 下午9:14
* Describe: DataSource Config
*/
@Configuration
public class DataSourceConfig {
@Autowired
Environment env;
@Bean(name = "ds1")
public DataSource dataSource1() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(env.getProperty("spring.datasource.db1.url"));
dataSource.setUsername(env.getProperty("spring.datasource.db1.username"));
dataSource.setPassword(env.getProperty("spring.datasource.db1.password"));
dataSource.setDriverClassName(env.getProperty("spring.datasource.db1.driver-class-name"));
return dataSource;
}
@Bean(name = "ds2")
public DataSource dataSource2() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(env.getProperty("spring.datasource.db2.url"));
dataSource.setUsername(env.getProperty("spring.datasource.db2.username"));
dataSource.setPassword(env.getProperty("spring.datasource.db2.password"));
dataSource.setDriverClassName(env.getProperty("spring.datasource.db2.driver-class-name"));
return dataSource;
}
@Bean(name = "dynamicDS1")//注意這個bean是mybatis的sqlSessionFacatory所管理的dataSource
public DataSource dataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
// 預設資料來源
dynamicDataSource.setDefaultTargetDataSource(dataSource1());
// 配置多資料來源
Map<Object, Object> dsMap = new HashMap(5);
dsMap.put("ds1", dataSource1());
dsMap.put("ds2", dataSource2());
dynamicDataSource.setTargetDataSources(dsMap);
return dynamicDataSource;
}
}
動態資料來源編寫
需要繼承AbstractRoutingDataSource類
/**
* Author: http://blog.csdn.net/neosmith/article/details/61202084
* Date: 17-11-2
* Time: 下午2:56
* Describe: 動態資料來源
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final Logger log = LoggerFactory.getLogger(DynamicDataSource.class);
@Override
protected Object determineCurrentLookupKey() {
log.debug("資料來源為{}", DataSourceContextHolder.getDB());
return DataSourceContextHolder.getDB();
}
}
編寫DataSourceContextHolder
/**
* Author: http://blog.csdn.net/neosmith/article/details/61202084
* Date: 17-11-2
* Time: 下午2:56
* Describe: DataSource ContextHolder
*/
public class DataSourceContextHolder {
public static final Logger log = LoggerFactory.getLogger(DataSourceContextHolder.class);
/**
* 預設資料來源
*/
public static final String DEFAULT_DS = "ds1";
/**
* 獲取當前執行緒
*/
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
// 設定資料來源名
public static void setDB(String dbType) {
log.debug("切換到{}資料來源", dbType);
contextHolder.set(dbType);
}
// 獲取資料來源名
public static String getDB() {
return (contextHolder.get());
}
// 清除資料來源名
public static void clearDB() {
contextHolder.remove();
}
}
咋們到時候只要呼叫setDB()方法即可實現資料來源的切換,下面使用Aop的方式進行動態切換。
編寫代理類
/**
* Author: http://blog.csdn.net/neosmith/article/details/61202084
* Date: 17-11-2
* Time: 下午3:01
* Describe: 動態資料來源代理類
* 邏輯:對方法@DB註解的方法進行切面換資料來源操作
*/
@Aspect
@Component
@Order(value=-1) //保證該AOP在@Transactional之前執行
public class DynamicDataSourceAspect {
@Before("@annotation(DB)")
public void beforeSwitchDS(JoinPoint point){
//獲得當前訪問的class
Class<?> className = point.getTarget().getClass();
//獲得訪問的方法名
String methodName = point.getSignature().getName();
//得到方法的引數的型別
Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
String dataSource = DataSourceContextHolder.DEFAULT_DS;
try {
// 得到訪問的方法物件
Method method = className.getMethod(methodName, argClass);
// 判斷是否存在@DS註解
if (method.isAnnotationPresent(DB.class)) {
DB annotation = method.getAnnotation(DB.class);
// 取出註解中的資料來源名
dataSource = annotation.value();
}
} catch (Exception e) {
e.printStackTrace();
}
// 切換資料來源
DataSourceContextHolder.setDB(dataSource);
}
@After("@annotation(DB)")
public void afterSwitchDS(JoinPoint point){
DataSourceContextHolder.clearDB();
}
}
自定義註解
/**
* Author: Starry.Teng
* Email: [email protected]
* Date: 17-11-2
* Time: 下午3:00
* Describe:
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.METHOD
})
public @interface DB {
String value() default "ds1";
}
serviceImpl
@DB("ds1")
public Object getDs1(){
Singer singer = singerMapper.findByName("陳奕迅");
logger.info("/n"+singer);
return null;
}
@DB("ds2")
public Object getDs2(){
Book book = bookMapper.findById(bookMapper.list().get(0).getId());
logger.info(book+"/n");
return null;
}
兩者比較
類別 | 多資料來源 | 動態資料來源 |
---|---|---|
作用 | 配置多個數據源,分模組開發 | 通過靈活的手段對資料庫進行靈活切庫 |
原理 | 例項化多個SsqlSessionFactory | Spring+AOP |
作用框架 | Mybatis | Spring |
應用場景 | 解耦比較大的專案,模組化開發 | 主從分佈,讀寫分離 |
知識點
上面的兩種方式都達到了”換資料來源”目的,只是實現的原理和方式不一樣而已,都是優虐,還是那句話,沒有最好的方法,只有在特定的環境下最適合的解決方案。
相關推薦
springBoot 動態資料來源以及Mybatis多資料來源
原文地址:https://blog.csdn.net/tengxing007/article/details/78424645前言在開發過程中可能需要用到多個數據源,比如一個專案(MySQL)就是和(SQL Server)混合使用,就需要使用多資料來源;如果業務場景比較復炸,
springboot 整合 pagehelper + tk-mybatis 多資料來源問題
閒暇之餘,寫點最近的收穫,寫一點心得,便於以後參考方便,另外可以幫助有這樣需求的人少走彎路。 整合多個數據源,很多部落格會提到springboot整合jdbcTemplete為例子,網上有很多,今天主要推薦的是整合 pagehelp
springboot+mybatis多資料來源配置,AOP註解動態切換資料來源
轉載至:https://blog.csdn.net/xiaosheng_papa/article/details/80218006 親測有效。 注:有些系統中已經配置了單資料來源,現在要轉成多資料來源,可能需要額外的配置。拿我自己當前專案來說: 專案在啟動類中配置了單資料來源:
基於SpirngBoot2.0+ 的 SpringBoot+Mybatis 多資料來源配置
Github 地址:github.com/Snailclimb/…(SpringBoot和其他常用技術的整合,可能是你遇到的講解最詳細的學習案例,力爭新手也能看懂並且能夠在看完之後獨立實踐。基於最新的 SpringBoot2.0+,是你學習SpringBoot 的最佳指南。) ,歡迎各位 Star。
新手也能看懂,基於SpirngBoot2.0+ 的 SpringBoot+Mybatis 多資料來源配置
Github 地址:https://github.com/Snailclimb/springboot-integration-examples(SpringBoot和其他常用技術的整合,可能是你遇到的講解最詳細的學習案例,力爭新手也能看懂並且能夠在看完之後獨立實踐。基於最新的 S
Mybatis(攔截器實現)通用mapper及全ORM實現(五)-- springboot+mybatis多資料來源設定
本篇實際上和mybatisext專案並沒有太大關係了,但在實際專案中脫離不開多個數據源,尤其是主從分離,同樣網上一些資料大同小異而且大部分並不能真正解決問題,所以單獨提出來說一下 假設我們就是要解決一個主從分離,資料來源定義在了application.properties中
springboot+mybatis多資料來源配置實現
簡單實現了根據註解動態切換資料來源,支援同一個資料庫的宣告式事務,但不支援JTA事務。處理流程: 根據配置的資料來源資訊,建立動態資料來源bean 利用DataSourceAspect處理@DataSource註解,設定當前要使用的具體資料來源 pom.xm
SpringBoot整合Mybatis多資料來源(Atomikos)
一、 Spring介紹 1.1、SpringBoot簡介 在您第1次接觸和學習Spring框架的時候,是否因為其繁雜的配置而退卻了?在你第n次使用Spring框架的時候,是否覺得一堆反覆黏貼的配置有一些厭煩?那麼您就不妨來試試使用Spring Boot來讓你更易上手,更簡
SpringBoot入門之基於Druid配置Mybatis多資料來源
上一篇瞭解了Druid進行配置連線池的監控和慢sql處理,這篇瞭解下使用基於基於Druid配置Mybatis多資料來源。SpringBoot預設配置資料庫連線資訊時只需設定url等屬性資訊就可以了,SpringBoot就會基於約定根據配置資訊例項化物件,但是一般大型的專案都是
springboot + mybatis 多資料來源
1:首先在springboot的 main啟動類上加 // boot自帶的DataSourceAutoConfiguration禁掉,因為它會讀取application.properties檔案的spring.datasource.*屬性並自動配置單資料來源。在@Sprin
eclipse 使用maven 搭建 springboot+mybatis + 多資料來源
DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` bigint(19) NOT NULL auto_increment, `loginname` varchar(64) default NULL, `name` varchar(64)
spring-boot (四) springboot+mybatis多資料來源最簡解決方案
配置檔案 pom包就不貼了比較簡單該依賴的就依賴,主要是資料庫這邊的配置: mybatis.config-locations=classpath:mybatis/mybatis-config.xml spring.datasource.test1.driverClassName = com.
springboot(七):springboot+mybatis多資料來源最簡解決方案
說起多資料來源,一般都來解決那些問題呢,主從模式或者業務比較複雜需要連線不同的分庫來支援業務。我們專案是後者的模式,網上找了很多,大都是根據jpa來做多資料來源解決方案,要不就是老的spring多資料來源解決方案,還有的是利用aop動態切換,感覺有點小複雜,其實
springboot+jpa+mybatis 多資料來源支援
package com.ehaoyao.paycenter.job.common.config;/** * ERP資料來源配置類 * * @author PF * Created by dell on 2018-05-04. */ import org.springframework.beans.
springboot整合mybatis多資料來源
application.properties #mysql [email protected]@ spring.datasource.primary.username= @[email protected] spring.datasource.prim
springboot+mybatis多資料來源配置方法及遇到的問題
這裡做的測試,兩個資料庫內表都一樣 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"
SpringBoot下配置Mybatis多資料來源
package com.ai.demos.manager; import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactor
Spring Boot MyBatis 動態資料來源切換、多資料來源,讀寫分離
轉載自:https://blog.csdn.net/u013360850/article/details/78861442本專案使用 Spring Boot 和 MyBatis 實現多資料來源,動態資料來源的切換;有多種不同的實現方式,在學習的過程中發現沒有文章將這些方式和常
Spring+Mybatis多資料來源配置(四)——AbstractRoutingDataSource實現資料來源動態切換
有時候需要在程式中動態切換資料來源,那麼這個系列的之前的博文所闡述的方法就不再使用了,總不能通過程式更改config.properties檔案的dataSource的值,然後再重啟web伺服器以便載入applicationContext.xml檔案。這裡講訴的是如何利用Ab
mybatis 多資料來源動態切換
>筆者主要從事c#開發,近期因為專案需要,搭建了一套spring-cloud微服務框架,集成了eureka服務註冊中心、 gateway閘道器過濾、admin服務監控、auth授權體系驗證,集成了redis、swagger、jwt、mybatis多資料來源等各項功能。 具體搭建過程後續另寫播客介紹。具體結構如