通過springboot+mybatis+druid配置動(dòng)態(tài)數(shù)據(jù)源
一、建數(shù)據(jù)庫和表
1.數(shù)據(jù)庫demo1放一張user表
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('1', 'aa'); INSERT INTO `user` VALUES ('2', 'bb');
2.數(shù)據(jù)庫demo2放一張role表
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for role -- ---------------------------- DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of role -- ---------------------------- INSERT INTO `role` VALUES ('1', 'CC'); INSERT INTO `role` VALUES ('2', 'DD');
二、pom.xml引入包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency> <!-- aop --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> <!-- alibaba druid--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!-- dynamic--> <dependency> <groupId>com.typesafe.dynamicdatasource</groupId> <artifactId>dynamic-data-source_2.11</artifactId> </dependency>
三、用generator插件生成user、role兩張表的實(shí)體類、mapper.java、mapper.xml
User.java Role.java UserMapper.java RoleMapper.java UserMapper.xml RoleMapper.xml
四、配置application.yml
server: port: 8088 mybatis: mapper-locations: classpath:mapper/*.xml spring: datasource: db1: url: jdbc:mysql://localhost:3306/demo1?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT username: root password: root type: com.alibaba.druid.pool.DruidDataSource #驅(qū)動(dòng)包 driver-class-name: com.mysql.cj.jdbc.Driver #初始連接數(shù) initial-size: 5 #最小空閑數(shù) min-idle: 5 #最大活動(dòng)數(shù) max-active: 20 #等待超時(shí)時(shí)間 max-wait: 60000 #配置間隔多久才進(jìn)行一次檢測(cè),檢測(cè)需要關(guān)閉的空閑連接,單位是毫秒 time-between-eviction-runs-millis: 60000 # 配置一個(gè)連接在池中最小生存的時(shí)間,單位是毫秒 min-evictable-idle-time-millis: 300000 #驗(yàn)證數(shù)據(jù)庫連接的查詢語句,MYSQL是select 1 validation-query: SELECT 1 FROM DUAL #空閑時(shí)測(cè)試,testOnBorrow和testOnReturn在生產(chǎn)環(huán)境一般是不開啟的,主要是性能考慮。失效連接主要通過testWhileIdle保證 test-while-idle: true test-on-borrow: false test-on-return: false #打開PSCache,并指定每個(gè)鏈接上的PSCache大小 pool-prepared-statements: true max-pool-prepared-statement-per-connection-size: 20 #配置監(jiān)控統(tǒng)計(jì)攔截的filters,去掉后監(jiān)控界面sql無法統(tǒng)計(jì),‘wall'用于防火墻,此處是filter修改的地方 filters: stat,wall #通過connectproperties屬性來打開mergesql功能:慢sql記錄 connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 #合并多個(gè)DruidDataSource useGlobalDataSourceStat: true db2: url: jdbc:mysql://localhost:3306/demo2?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT username: root password: root type: com.alibaba.druid.pool.DruidDataSource #驅(qū)動(dòng)包 driver-class-name: com.mysql.cj.jdbc.Driver #初始連接數(shù) initial-size: 5 #最小空閑數(shù) min-idle: 5 #最大活動(dòng)數(shù) max-active: 20 #等待超時(shí)時(shí)間 max-wait: 60000 #配置間隔多久才進(jìn)行一次檢測(cè),檢測(cè)需要關(guān)閉的空閑連接,單位是毫秒 time-between-eviction-runs-millis: 60000 # 配置一個(gè)連接在池中最小生存的時(shí)間,單位是毫秒 min-evictable-idle-time-millis: 300000 #驗(yàn)證數(shù)據(jù)庫連接的查詢語句,MYSQL是select 1 validation-query: SELECT 1 FROM DUAL #空閑時(shí)測(cè)試,testOnBorrow和testOnReturn在生產(chǎn)環(huán)境一般是不開啟的,主要是性能考慮。失效連接主要通過testWhileIdle保證 test-while-idle: true test-on-borrow: false test-on-return: false #打開PSCache,并指定每個(gè)鏈接上的PSCache大小 pool-prepared-statements: true max-pool-prepared-statement-per-connection-size: 20 #配置監(jiān)控統(tǒng)計(jì)攔截的filters,去掉后監(jiān)控界面sql無法統(tǒng)計(jì),‘wall'用于防火墻,此處是filter修改的地方 filters: stat,wall #通過connectproperties屬性來打開mergesql功能:慢sql記錄 connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 #合并多個(gè)DruidDataSource useGlobalDataSourceStat: true
五、啟動(dòng)類掃描mapper.java文件
@SpringBootApplication @MapperScan("com.example.demo.dao") public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
六、定義DataSourceConfig, 將application.yml中的配置導(dǎo)入DataSource中,并注入到bean
@Configuration public class DataSourceConfig { //從配置文件配置數(shù)據(jù)源 @Primary @Bean(name="datasource1") @ConfigurationProperties("spring.datasource.db1") public DataSource dataSource1(){ return new DruidDataSource(); } //從配置文件配置數(shù)據(jù)源 @Bean(name="datasource2") @ConfigurationProperties("spring.datasource.db2") public DataSource dataSource2(){ return new DruidDataSource(); } //動(dòng)態(tài)數(shù)據(jù)源 進(jìn)行數(shù)據(jù)源切換 @Bean(name="dynamicDataSource") public DataSource dynamicDataSource(){ DynamicDataSource dynamicDatasource=new DynamicDataSource(); //設(shè)置默認(rèn)數(shù)據(jù)源 dynamicDatasource.setDefaultTargetDataSource(dataSource1()); //配置多數(shù)據(jù)源 Map<Object,Object> dsMap=new HashMap<>(); dsMap.put("datasource1",dataSource1()); dsMap.put("datasource2",dataSource2()); //將多數(shù)據(jù)源放到數(shù)據(jù)源池中 dynamicDatasource.setTargetDataSources(dsMap); return dynamicDatasource; } }
七、定義動(dòng)態(tài)數(shù)據(jù)源切換類DynamicDataSourceContextHolder
public class DynamicDataSourceContextHolder { private static final ThreadLocal<String> contextHolder=new ThreadLocal<>(); //設(shè)置數(shù)據(jù)源名稱 public static void setDB(String dbType){ contextHolder.set(dbType); } //獲取數(shù)據(jù)源名稱 public static String getDB(){ return contextHolder.get(); } //清除數(shù)據(jù)源名 public static void clearDB(){ contextHolder.remove(); } }
八、定義獲取動(dòng)態(tài)數(shù)據(jù)源類DynamicDataSource
public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DynamicDataSourceContextHolder.getDB(); } }
九、定義mybatis配置類,將DynamicDataSource放入SqlSessionFactoryBean中
@EnableTransactionManagement @Configuration public class MyBatisConfig { @Resource(name = "dynamicDataSource") private DataSource dynamicDataSource; @Bean public SqlSessionFactory sqlSessionFactory() throws Exception { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dynamicDataSource);//將動(dòng)態(tài)數(shù)據(jù)源bean配置到sqlsessionfactory sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml")); return sqlSessionFactoryBean.getObject(); } @Bean public PlatformTransactionManager platformTransactionManager() { return new DataSourceTransactionManager(dynamicDataSource); } }
十、定義用于切換數(shù)據(jù)源的注解TargetDataSource
@Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface TargetDataSource { String value() default "datasource1"; }
十一、定義切面DynamicDataSourceAspect,用于攔截注解,并執(zhí)行數(shù)據(jù)源切換功能
@Aspect @Component public class DynamicDataSourceAspect { @Before("@annotation(targetDataSource)") public void beforeSwitchDS(JoinPoint point,TargetDataSource targetDataSource){ DynamicDataSourceContextHolder.setDB(targetDataSource.value()); } @After("@annotation(targetDataSource)") public void afterSwitchDS(JoinPoint point,TargetDataSource targetDataSource){ DynamicDataSourceContextHolder.clearDB(); } }
十二、測(cè)試類Test
@RestController public class Test { @Autowired private RoleMapper roleMapper; @Autowired private UserMapper userMapper; //未使用TargetDataSource注解,則使用默認(rèn)數(shù)據(jù)源,即datasource1 @RequestMapping("/ds1") public String selectDataSource1(){ return userMapper.selectByPrimaryKey(1).toString(); } //使用了注解,則數(shù)據(jù)源為注解中指定的datasource2 @RequestMapping("/ds2") @TargetDataSource("datasource2") public String selectDataSource2(){ return roleMapper.selectByPrimaryKey(1).toString(); } }
測(cè)試
1.輸入
http://localhost:8088/ds1
返回
↓
2.輸入
http://localhost:8088/ds2
返回
↓
結(jié)論:兩次請(qǐng)求分別從不同的數(shù)據(jù)庫獲取到了數(shù)據(jù),多數(shù)據(jù)源配置成功!
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- SpringBoot集成Druid實(shí)現(xiàn)多數(shù)據(jù)源的兩種方式
- SpringBoot整合Mybatis-Plus+Druid實(shí)現(xiàn)多數(shù)據(jù)源配置功能
- springboot mybatis druid配置多數(shù)據(jù)源教程
- 關(guān)于springboot配置druid數(shù)據(jù)源不生效問題(踩坑記)
- 使用springboot+druid雙數(shù)據(jù)源動(dòng)態(tài)配置操作
- springboot配置多數(shù)據(jù)源并集成Druid和mybatis的操作
- SpringBoot環(huán)境Druid數(shù)據(jù)源使用及特點(diǎn)
- Springboot mybatis plus druid多數(shù)據(jù)源解決方案 dynamic-datasource的使用詳解
- SpringBoot整合Druid數(shù)據(jù)源過程詳解
- springboot 動(dòng)態(tài)數(shù)據(jù)源的實(shí)現(xiàn)方法(Mybatis+Druid)
- Spring Boot+Mybatis+Druid+PageHelper實(shí)現(xiàn)多數(shù)據(jù)源并分頁的方法
- 詳解Spring Boot整合Mybatis實(shí)現(xiàn) Druid多數(shù)據(jù)源配置
- spring使用xml方式整合Druid數(shù)據(jù)源連接池
相關(guān)文章
mybatis設(shè)置sql執(zhí)行時(shí)間超時(shí)時(shí)間的方法
本文主要介紹了mybatis設(shè)置sql執(zhí)行時(shí)間超時(shí)時(shí)間的方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02java實(shí)現(xiàn)Excel的導(dǎo)入、導(dǎo)出
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)Excel的導(dǎo)入、導(dǎo)出的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06Mybatis-plus如何在xml中傳入自定義的SQL語句
這篇文章主要介紹了Mybatis-plus如何在xml中傳入自定義的SQL語句問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05使用Spring Boot+MyBatis框架做查詢操作的示例代碼
這篇文章主要介紹了使用Spring Boot+MyBatis框架做查詢操作的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-10-10mybatis中數(shù)據(jù)加密與解密的實(shí)現(xiàn)
數(shù)據(jù)加解密的實(shí)現(xiàn)方式多種多樣,在mybatis環(huán)境中數(shù)據(jù)加解密變得非常簡單易用,本文主要介紹了mybatis中數(shù)據(jù)加密與解密的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03Java日期時(shí)間與正則表達(dá)式超詳細(xì)整理(適合新手入門)
如果使用得當(dāng),正則表達(dá)式是匹配各種模式的強(qiáng)大工具,下面這篇文章主要給大家介紹了關(guān)于Java日期時(shí)間與正則表達(dá)式超詳細(xì)整理的相關(guān)資料,本文非常適合新手入門,需要的朋友可以參考下2023-04-04