Skip to content

Commit

Permalink
feat: 添加动态数据源代码
Browse files Browse the repository at this point in the history
  • Loading branch information
mianshenglee committed Jan 13, 2020
1 parent 2cee280 commit bb41587
Show file tree
Hide file tree
Showing 21 changed files with 726 additions and 0 deletions.
31 changes: 31 additions & 0 deletions multi-datasource/dynamic-datasource/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/

### VS Code ###
.vscode/
79 changes: 79 additions & 0 deletions multi-datasource/dynamic-datasource/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>me.mason.demo</groupId>
<artifactId>dynamic-datasource</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dynamic-datasource</name>
<description>Demo project for dynamic datasource</description>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<!--spring boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--mysql 驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>
26 changes: 26 additions & 0 deletions multi-datasource/dynamic-datasource/sql/tables-master.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

/*Table structure for table `test_user` */

DROP TABLE IF EXISTS `test_user`;

CREATE TABLE `test_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL COMMENT '姓名',
`phone` varchar(32) DEFAULT NULL COMMENT '手机号',
`title` varchar(32) DEFAULT NULL COMMENT '职称职别',
`email` varchar(128) DEFAULT NULL COMMENT '邮箱',
`gender` varchar(32) DEFAULT NULL COMMENT '性别',
`date_of_birth` date DEFAULT NULL COMMENT '出生时间',
`deleted` tinyint(1) DEFAULT '0' COMMENT '1:已删除,0:未删除',
`sys_create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`sys_create_user` varchar(255) DEFAULT NULL,
`sys_update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`sys_update_user` varchar(255) DEFAULT NULL,
`record_version` bigint(20) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7013 DEFAULT CHARSET=utf8;

/*Data for the table `test_user` */

insert into `test_user`(`id`,`name`,`phone`,`title`,`email`,`gender`,`date_of_birth`,`deleted`,`sys_create_time`,`sys_create_user`,`sys_update_time`,`sys_update_user`,`record_version`) values (3497,'王**','13800000000','test','[email protected]','1','1958-07-01',0,'2019-03-28 14:53:44','admin','2019-05-31 11:17:55','admin',0),(3500,'林**','13800000000',NULL,NULL,'1',NULL,0,'2019-03-28 14:53:44','admin','2019-05-31 11:21:47','admin',0),(3508,'高**','13800000000','test',NULL,'2','1978-05-20',0,'2019-03-28 14:53:44','admin','2019-05-31 11:17:55','admin',0),(7005,'test4',NULL,'test4','[email protected]','1',NULL,0,'2020-01-06 16:19:23',NULL,'2020-01-07 11:29:10','admin',0),(7006,'test5',NULL,'new title','[email protected]','1',NULL,0,'2020-01-06 16:48:52',NULL,'2020-01-07 11:19:48','admin',0),(7007,'test6',NULL,NULL,'[email protected]',NULL,NULL,1,'2020-01-06 16:48:52',NULL,'2020-01-07 09:46:23',NULL,0);

26 changes: 26 additions & 0 deletions multi-datasource/dynamic-datasource/sql/tables-slave.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

/*Table structure for table `test_user` */

DROP TABLE IF EXISTS `test_user`;

CREATE TABLE `test_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL COMMENT '姓名',
`phone` varchar(32) DEFAULT NULL COMMENT '手机号',
`title` varchar(32) DEFAULT NULL COMMENT '职称职别',
`email` varchar(128) DEFAULT NULL COMMENT '邮箱',
`gender` varchar(32) DEFAULT NULL COMMENT '性别',
`date_of_birth` date DEFAULT NULL COMMENT '出生时间',
`deleted` tinyint(1) DEFAULT '0' COMMENT '1:已删除,0:未删除',
`sys_create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`sys_create_user` varchar(255) DEFAULT NULL,
`sys_update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`sys_update_user` varchar(255) DEFAULT NULL,
`record_version` bigint(20) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7013 DEFAULT CHARSET=utf8;

/*Data for the table `test_user` */

insert into `test_user`(`id`,`name`,`phone`,`title`,`email`,`gender`,`date_of_birth`,`deleted`,`sys_create_time`,`sys_create_user`,`sys_update_time`,`sys_update_user`,`record_version`) values (3520,'刘**','13800000000',NULL,NULL,'1','1984-09-25',0,'2019-03-28 14:53:44','admin','2019-05-31 11:17:55','admin',0),(6999,'张*','13800000000','TEST','[email protected]','1','1990-06-10',0,'2019-03-28 14:53:44','admin','2019-05-31 11:17:55','admin',0),(7003,'test_add1','13800000000','TEST1','[email protected]','1','1947-11-01',0,'2019-06-04 23:17:48',NULL,'2019-11-07 10:40:43',NULL,0),(7004,'test_add2','13800000000','test2','[email protected]','1','1958-07-01',0,'2019-06-04 23:17:48',NULL,'2019-11-07 11:13:06',NULL,0);

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package me.mason.demo.dynamicdatasource;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DynamicDatasourceApplication {

public static void main(String[] args) {
SpringApplication.run(DynamicDatasourceApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package me.mason.demo.dynamicdatasource.annotation;

import me.mason.demo.dynamicdatasource.constants.DataSourceConstants;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* 自定义数据源注解
*
* @author: mason
* @since: 2020/1/9
**/
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DS {
/**
* 数据源名称
* @return
*/
String value() default DataSourceConstants.DS_KEY_MASTER;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package me.mason.demo.dynamicdatasource.aop;

import me.mason.demo.dynamicdatasource.annotation.DS;
import me.mason.demo.dynamicdatasource.context.DynamicDataSourceContextHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
* TODO
*
* @author: mason
* @since: 2020/1/9
**/
@Aspect
@Component
public class DynamicDataSourceAspect {
@Pointcut("@annotation(me.mason.demo.dynamicdatasource.annotation.DS)")
public void dataSourcePointCut(){

}

@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
String dsKey = getDSAnnotation(joinPoint).value();
DynamicDataSourceContextHolder.setContextKey(dsKey);
try{
return joinPoint.proceed();
}finally {
DynamicDataSourceContextHolder.removeContextKey();
}
}

/**
* 根据类或方法获取数据源注解
* @param joinPoint
* @return
*/
private DS getDSAnnotation(ProceedingJoinPoint joinPoint){
Class<?> targetClass = joinPoint.getTarget().getClass();
DS dsAnnotation = targetClass.getAnnotation(DS.class);
// 先判断类的注解,再判断方法注解
if(Objects.nonNull(dsAnnotation)){
return dsAnnotation;
}else{
MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
return methodSignature.getMethod().getAnnotation(DS.class);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package me.mason.demo.dynamicdatasource.config;

import me.mason.demo.dynamicdatasource.context.DynamicDataSourceContextHolder;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
* 动态数据源
*
* @author: mason
* @since: 2020/1/9
**/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceContextHolder.getContextKey();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package me.mason.demo.dynamicdatasource.config;

import me.mason.demo.dynamicdatasource.constants.DataSourceConstants;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
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.context.annotation.PropertySource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
* 动态数据源配置
*
* @author: mason
* @since: 2020/1/9
**/
// 添加此配置,否则 报`The dependencies of some of the beans in the application context form a cycle`
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class })
@Configuration
@PropertySource("classpath:config/jdbc.properties")
@MapperScan(basePackages = "me.mason.demo.dynamicdatasource.mapper")
public class DynamicDataSourceConfig {
@Bean(DataSourceConstants.DS_KEY_MASTER)
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}

@Bean(DataSourceConstants.DS_KEY_SLAVE)
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource slaveDataSource() {
return DataSourceBuilder.create().build();
}

@Bean
@Primary
public DataSource dynamicDataSource() {
Map<Object, Object> dataSourceMap = new HashMap<>(2);
dataSourceMap.put(DataSourceConstants.DS_KEY_MASTER, masterDataSource());
dataSourceMap.put(DataSourceConstants.DS_KEY_SLAVE, slaveDataSource());
//设置动态数据源
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setTargetDataSources(dataSourceMap);
dynamicDataSource.setDefaultTargetDataSource(masterDataSource());

return dynamicDataSource;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package me.mason.demo.dynamicdatasource.constants;

/**
* 数据源常量
*
* @author: mason
* @since: 2020/1/9
**/
public class DataSourceConstants {
/**
* master数据源
*/
public static final String DS_KEY_MASTER = "master";
/**
* slave数据源
*/
public static final String DS_KEY_SLAVE = "slave";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package me.mason.demo.dynamicdatasource.context;

import me.mason.demo.dynamicdatasource.constants.DataSourceConstants;

/**
* 动态数据源名称上下文处理
*
* @author: mason
* @since: 2020/1/9
**/
public class DynamicDataSourceContextHolder {

/**
* 动态数据源名称上下文
*/
private static final ThreadLocal<String> DATASOURCE_CONTEXT_KEY_HOLDER = new ThreadLocal<>();

/**
* 设置数据源
* @param key
*/
public static void setContextKey(String key){
System.out.println("切换数据源"+key);
DATASOURCE_CONTEXT_KEY_HOLDER.set(key);
}

/**
* 获取数据源名称
* @return
*/
public static String getContextKey(){
String key = DATASOURCE_CONTEXT_KEY_HOLDER.get();
return key == null?DataSourceConstants.DS_KEY_MASTER:key;
}

/**
* 删除当前数据源名称
*/
public static void removeContextKey(){
DATASOURCE_CONTEXT_KEY_HOLDER.remove();
}
}
Loading

0 comments on commit bb41587

Please sign in to comment.