首页 技术 正文
技术 2022年11月17日
0 收藏 483 点赞 2,378 浏览 5975 个字

1、自定义DataSource

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;/**
* @Description 动态数据源
* AbstractRoutingDataSource(每执行一次数据库,动态获取DataSource)
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceContextHolder.getDataSourceType();
}
}

2、数据源切换器

import java.util.ArrayList;
import java.util.List;/**
* @Description 动态数据源上下文管理
*/
public class DynamicDataSourceContextHolder { //存放当前线程使用的数据源类型信息
private static final ThreadLocal<Object> contextHolder = new ThreadLocal<>();
//存放数据源id
public static List<Object> dataSourceIds = new ArrayList<>(); //当从库数据源大于1个时,可以配置轮询方式
public static List<Object> slaveDataSourceKeys = new ArrayList<>(); //设置数据源
public static void setDataSourceType(String dataSourceType) {
if(dataSourceIds.contains(dataSourceType)) {
contextHolder.set(dataSourceType);
}
} //获取数据源
public static Object getDataSourceType() {
return contextHolder.get();
} //清除数据源
public static void clearDataSourceType() {
contextHolder.remove();
}
}

3、代理类事物切换数据源

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;/**
* @Description 动态数据源通知
*/
@Aspect
@Order(-1)//保证在@Transactional之前执行
@Component
public class DynamicDattaSourceAspect { //改变数据源,方法上存在事物的注解,则走主库
@Before("@annotation(transactional)")
public void changeDataSource(JoinPoint joinPoint, Transactional transactional) {
DynamicDataSourceContextHolder.setDataSourceType("master");
} @After("@annotation(transactional)")
public void clearDataSource(JoinPoint joinPoint, Transactional transactional) {
DynamicDataSourceContextHolder.clearDataSourceType();
}
}

4、数据源Bean注册器

import java.util.HashMap;
import java.util.Map;import javax.sql.DataSource;import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.flyway.FlywayDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;import tk.mybatis.spring.annotation.MapperScan;/**
* @Description 注册动态数据源
* 初始化数据源和提供了执行动态切换数据源的工具类
*/
@Configuration
@MapperScan(basePackages="com.xxxx.*.mapper")
public class DynamicDataSourceRegister{
protected Logger logger = LoggerFactory.getLogger(getClass()); @Value("${datasource.type}")
private Class<? extends DataSource> dataSourceType; @Bean
@Primary
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dynamicDataSource());
PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
sessionFactory.setMapperLocations(pathMatchingResourcePatternResolver.getResources("classpath*:mapper/*Mapper.xml"));
Resource resource = pathMatchingResourcePatternResolver.getResource("classpath:mybatis-setting.xml");
sessionFactory.setConfigLocation(resource);
return sessionFactory.getObject();
} @FlywayDataSource//指定主库为flyway的数据源
@Bean(name = "masterDataSource")
@ConfigurationProperties(prefix = "master.datasource")
public DataSource masterDataSource(){
return DataSourceBuilder.create().type(dataSourceType).build();
} @Bean(name = "slaveDataSource")
@ConfigurationProperties(prefix = "slave.datasource")
public DataSource slaveDataSource(){
return DataSourceBuilder.create().type(dataSourceType).build();
} @Bean("dynamicDataSource")
public DataSource dynamicDataSource() {
DynamicDataSource dynamicRoutingDataSource = new DynamicDataSource();
Map<Object, Object> dataSourceMap = new HashMap<>(4);
dataSourceMap.put("master", masterDataSource());
dataSourceMap.put("slaveDataSource", slaveDataSource()); // 将 slave 数据源作为默认指定的数据源
dynamicRoutingDataSource.setDefaultTargetDataSource(slaveDataSource());
// 将 master 和 slave 数据源作为指定的数据源
dynamicRoutingDataSource.setTargetDataSources(dataSourceMap); // 将数据源的 key 放到数据源上下文的 key 集合中,用于切换时判断数据源是否有效
DynamicDataSourceContextHolder.dataSourceIds.addAll(dataSourceMap.keySet()); // 将 Slave 数据源的 key 放在集合中,用于轮循
DynamicDataSourceContextHolder.slaveDataSourceKeys.addAll(dataSourceMap.keySet());
DynamicDataSourceContextHolder.slaveDataSourceKeys.remove("master");
return dynamicRoutingDataSource;
} @Bean
public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dynamicDataSource());
}}

6、资源文件配置

#datasource master
datasource.type=com.alibaba.druid.pool.DruidDataSource
#master
master.datasource.url=jdbc:mysql://localhost:3306/haogonge_dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
master.datasource.username=root
master.datasource.password=root
master.datasource.driver-class-name=com.mysql.jdbc.Driver
master.datasource.pool.initialSize=3
master.datasource.pool.maxActive=15
master.datasource.pool.minIdle=3
master.datasource.pool.maxWait=60000
master.datasource.pool.timeBetweenEvictionRunsMillis=60000
master.datasource.pool.minEvictableIdleTimeMillis=120000
#slave
slave.datasource.url=jdbc:mysql://localhost:3306/haogonge_dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
slave.datasource.username=root
slave.datasource.password=root
slave.datasource.driver-class-name=com.mysql.jdbc.Driver
slave.datasource.pool.initialSize=3
slave.datasource.pool.maxActive=15
slave.datasource.pool.minIdle=3
slave.datasource.pool.maxWait=60000
slave.datasource.pool.timeBetweenEvictionRunsMillis=60000
slave.datasource.pool.minEvictableIdleTimeMillis=120000

  

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,082
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,556
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,405
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,179
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,815
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,898