实现数据源动态切换,希望能帮到需要的人,代码copy就能用
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.4.7.RELEASEversion>
parent>
<groupId>com.crr.zglgroupId>
<artifactId>apiartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<java.version>1.8java.version>
<jackson-dataformat-yaml.version>2.8.3jackson-dataformat-yaml.version>
<junit.version>4.12junit.version>
<log4j.version>2.6.2log4j.version>
<druid.version>1.1.3druid.version>
<apache-commons-pool2.version>2.4.2apache-commons-pool2.version>
<mysql-connector-java.version>6.0.5mysql-connector-java.version>
<mybatis-spring-boot-starter.version>1.1.1mybatis-spring-boot-starter.version>
<jersey-client.version>2.23.1jersey-client.version>
<jedis.version>2.9.0jedis.version>
<apache-commons-lang3.version>3.4apache-commons-lang3.version>
<commons-lang.version>2.6commons-lang.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-loggingartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-loggingartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-redisartifactId>
<version>1.4.7.RELEASEversion>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>1.3.1version>
dependency>
<dependency>
<groupId>com.jayway.jsonpathgroupId>
<artifactId>json-pathartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql-connector-java.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformatgroupId>
<artifactId>jackson-dataformat-yamlartifactId>
<version>${jackson-dataformat-yaml.version}version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>${junit.version}version>
dependency>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-coreartifactId>
<version>${log4j.version}version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>${druid.version}version>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-pool2artifactId>
<version>${apache-commons-pool2.version}version>
dependency>
<dependency>
<groupId>org.apache.tomcatgroupId>
<artifactId>tomcat-jdbcartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql-connector-java.version}version>
dependency>
<dependency>
<groupId>org.glassfish.jersey.coregroupId>
<artifactId>jersey-clientartifactId>
<version>${jersey-client.version}version>
dependency>
<dependency>
<groupId>redis.clientsgroupId>
<artifactId>jedisartifactId>
<version>${jedis.version}version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-log4j2artifactId>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformatgroupId>
<artifactId>jackson-dataformat-yamlartifactId>
dependency>
<dependency>
<groupId>commons-beanutilsgroupId>
<artifactId>commons-beanutilsartifactId>
<exclusions>
<exclusion>
<artifactId>commons-loggingartifactId>
<groupId>commons-logginggroupId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-lang3artifactId>
<version>${apache-commons-lang3.version}version>
dependency>
<dependency>
<groupId>commons-langgroupId>
<artifactId>commons-langartifactId>
<version>${commons-lang.version}version>
dependency>
<dependency>
<groupId>org.apache.zookeepergroupId>
<artifactId>zookeeperartifactId>
<version>3.5.3-betaversion>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-clientartifactId>
<version>4.0.0version>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-frameworkartifactId>
<version>2.7.1version>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.8.10version>
dependency>
dependencies>
<build>
<finalName>apifinalName>
<resources>
<resource>
<directory>${basedir}/src/main/resourcesdirectory>
<includes>
<include>**/*include>
includes>
resource>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.xmlinclude>
includes>
<filtering>falsefiltering>
resource>
resources>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
spring.datasource.masterMapperLocations=classpath:com/rrc/zgl/dao/*/impl/*Mapper.xml
#master数据源
spring.datasource.master.url=jdbc:mysql://localhost:3306/zgl?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
spring.datasource.master.username=root
spring.datasource.master.password=123456
spring.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.master.initialSize=5
spring.datasource.master.minIdle=5
spring.datasource.master.maxActive= 20
spring.datasource.master.maxWait= 60000
spring.datasource.master.timeBetweenEvictionRunsMillis= 60000
spring.datasource.master.minEvictableIdleTimeMillis= 300000
spring.datasource.master.validationQuery= SELECT 1
spring.datasource.master.testWhileIdle= true
spring.datasource.master.testOnBorrow= false
spring.datasource.master.testOnReturn= false
spring.datasource.master.poolPreparedStatements= true
spring.datasource.master.maxPoolPreparedStatementPerConnectionSize= 20
spring.datasource.master.filters= stat,wall,log4j
spring.datasource.master.connectionProperties= druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
spring.datasource.master.useGlobalDataSourceStat= true
#cluster数据源
spring.datasource.cluster.url=jdbc:mysql://localhost:3306/zgl1?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
spring.datasource.cluster.username=root
spring.datasource.cluster.password=123456
spring.datasource.cluster.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.cluster.initialSize=5
spring.datasource.cluster.minIdle=5
spring.datasource.cluster.maxActive= 20
spring.datasource.cluster.maxWait= 60000
spring.datasource.cluster.timeBetweenEvictionRunsMillis= 60000
spring.datasource.cluster.minEvictableIdleTimeMillis= 300000
spring.datasource.cluster.validationQuery= SELECT 1
spring.datasource.cluster.testWhileIdle= true
spring.datasource.cluster.testOnBorrow= false
spring.datasource.cluster.testOnReturn= false
spring.datasource.cluster.poolPreparedStatements= true
spring.datasource.cluster.maxPoolPreparedStatementPerConnectionSize= 20
spring.datasource.cluster.filters= stat,wall,log4j
spring.datasource.cluster.connectionProperties= druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
spring.datasource.cluster.useGlobalDataSourceStat= true
@SpringBootApplication
@PropertySource(value = {"classpath:dataSource.properties"})
@ServletComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
4.配置数据源1
@Configuration
@EnableTransactionManagement
public class ClusterDruidDataSourceConfig {
@Value("${spring.datasource.masterMapperLocations}")
private String clusterMapperLocations;
@ConfigurationProperties(prefix = "spring.datasource.cluster")
@Bean(name = "clusterDataSource")
public DataSource clusterDataSource() {
return new DruidDataSource();
}
/**
* SqlSessionFactory配置
*
* @return
* @throws Exception
*/
@Bean(name = "clusterSqlSessionFactory")
public SqlSessionFactory clusterSqlSessionFactory(
@Qualifier("clusterDataSource") DataSource dataSource
) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
//配置mapper文件位置
sqlSessionFactoryBean.setMapperLocations(resolver.getResources(clusterMapperLocations));
return sqlSessionFactoryBean.getObject();
}
/**
* 配置事物管理器
*
* @return
*/
@Bean(name = "clusterTransactionManager")
public DataSourceTransactionManager clusterTransactionManager(
@Qualifier("clusterDataSource") DataSource dataSource
) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource);
return dataSourceTransactionManager;
}
@Configuration
@EnableTransactionManagement
public class MasterDruidDataSourceConfig {
@Value("${spring.datasource.masterMapperLocations}")
private String masterMapperLocations;
@ConfigurationProperties(prefix = "spring.datasource.master")
@Bean(name = "masterDataSource")
@Primary
public DataSource masterDataSource() {
return new DruidDataSource();
}
/**
* SqlSessionFactory配置
*
* @return
* @throws Exception
*/
@Bean(name = "masterSqlSessionFactory")
@Primary
public SqlSessionFactory masterSqlSessionFactory(
@Qualifier("masterDataSource") DataSource dataSource
) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
// 配置mapper文件位置
sqlSessionFactoryBean.setMapperLocations(resolver.getResources(masterMapperLocations));
return sqlSessionFactoryBean.getObject();
}
/**
* 配置事物管理器
*
* @return
*/
@Bean(name = "masterTransactionManager")
@Primary
public DataSourceTransactionManager masterTransactionManager(
@Qualifier("masterDataSource") DataSource dataSource
) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource);
return dataSourceTransactionManager;
}
}
@Aspect
@Component
public class DynamicDataSourceAspect {
private Logger logger = LoggerFactory.getLogger(DynamicDataSourceAspect.class);
@Around("execution(* com.crr.zgl.dao..*.*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Signature signature = pjp.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
boolean methodAnnotation = method.isAnnotationPresent(TargetDataSource.class);
TargetDataSource targetDataSource = null;
if (methodAnnotation) {
targetDataSource = method.getAnnotation(TargetDataSource.class);
} else {
Class clazz[] = pjp.getTarget().getClass().getInterfaces();
targetDataSource = (TargetDataSource) clazz[0].getAnnotation(TargetDataSource.class);
}
if (targetDataSource != null) {
DynamicDataSourceHolder.setDataSource(targetDataSource.dataSource());
logger.debug("mybatis接口: " + (method.getDeclaringClass() + "." + method.getName()) + " 设置数据源 key is " + targetDataSource.dataSource());
}
Object result = pjp.proceed();//执行方法
DynamicDataSourceHolder.clearDataSource();
return result;
}
}
/**
* 多数据进行切换
*/
public class DynamicDataSourceHolder {
//使用ThreadLocal把数据源与当前线程绑定
private static final ThreadLocal dataSources = new ThreadLocal();
public static void setDataSource(String dataSourceName) {
dataSources.set(dataSourceName);
}
public static String getDataSource() {
return (String) dataSources.get();
}
public static void clearDataSource() {
dataSources.remove();
}
}
/**
* 动态数据源获取sessionfactory
* @Author:zhangguangliang
*/
public class DynamicSqlSessionTemplate extends SqlSessionTemplate {
private static Logger logger = LoggerFactory.getLogger(DynamicSqlSessionTemplate.class);
private SqlSessionFactory sqlSessionFactory;
private ExecutorType executorType;
private SqlSession sqlSessionProxy;
private PersistenceExceptionTranslator exceptionTranslator;
private Map
@WebFilter(filterName="druidWebStatFilter",urlPatterns="/*",
initParams={
@WebInitParam(name="exclusions",value="*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")// 忽略资源
})
public class DruidStatFilter extends WebStatFilter {
}
@WebServlet(urlPatterns = "/druid/*",
initParams = {
@WebInitParam(name = "allow", value = "127.0.0.1"),// IP白名单 (没有配置或者为空,则允许所有访问)
//@WebInitParam(name="deny",value="192.168.16.111"),// IP黑名单 (存在共同时,deny优先于allow)
//@WebInitParam(name="loginUsername",value="zgl"),// 用户名
//@WebInitParam(name="loginPassword",value="zgl"),// 密码
@WebInitParam(name = "resetEnable", value = "false")// 禁用HTML页面上的“Reset All”功能
})
public class DruidStatViewServlet extends StatViewServlet {
// 按照BeanId来拦截配置 用来bean的监控
/* @Bean(value = "druid-stat-interceptor")
public DruidStatInterceptor DruidStatInterceptor() {
DruidStatInterceptor druidStatInterceptor = new DruidStatInterceptor();
return druidStatInterceptor;
}
@Bean
public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
beanNameAutoProxyCreator.setProxyTargetClass(true);
// 设置要监控的bean的id
beanNameAutoProxyCreator.setBeanNames("clusterSqlSessionFactory","masterTransactionManager");
beanNameAutoProxyCreator.setInterceptorNames("druid-stat-interceptor");
return beanNameAutoProxyCreator;
}*/
}
@TargetDataSource(dataSource = DataSourceConfig.masterDataSource_)
@Repository(value = "userMapper")
public interface UserMapper {
int deleteByPrimaryKey(Long id);
@TargetDataSource(dataSource = DataSourceConfig.clusterDataSource_)
int insert(User record);
int insertSelective(User record);
User selectByPrimaryKey(Long id);
int updateByPrimaryKeySelective(User record);
int updateByPrimaryKey(User record);
}
@Transactional(transactionManager = "clusterTransactionManager",rollbackFor=Exception.class)
public String test() {
User user = new User();
user.setName("124");
user.setPassword("setPassword");
int insert1 = zgl1UserMapper.insert(user);
//int insert = userMapper.insert(user);
return "success";
}