参考了https://www.cnblogs.com/yi1036943655/p/9251425.html
1.pom.xml
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<!-- oracle驱动 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!--AbstractRoutingDataSource-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
2.application.properties
server.port=8181
spring.datasource.read-db.jdbc-url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
spring.datasource.read-db.username=orcl1
spring.datasource.read-db.password=1
spring.datasource.read-db.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.read-db.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.write-db.jdbc-url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
spring.datasource.write-db.username=orcl2
spring.datasource.write-db.password=1
spring.datasource.write-db.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.write-db.driver-class-name=oracle.jdbc.driver.OracleDriver
mybatis.type-aliases-package=com.yudu.db.pojo
3.多数据源配置类
package com.yudu.db.config;
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.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class DataSourceConfig {
@ConfigurationProperties(prefix = "spring.datasource.read-db")
@Bean(name="readDb")
public DataSource readDb(){
return DataSourceBuilder.create().build();
}
@ConfigurationProperties(prefix = "spring.datasource.write-db")
@Bean(name="writeDb")
public DataSource writeDb(){
return DataSourceBuilder.create().build();
}
/**
* 动态数据源: 通过AOP在不同数据源之间动态切换
* @return
*/
@Primary
@Bean(name = "dynamicDataSource")
public DataSource dynamicDataSource(){
DynamicDataSource dynamicDataSource = new DynamicDataSource();
// 默认数据源
dynamicDataSource.setDefaultTargetDataSource(readDb());
// 配置多数据源
Map<Object, Object> dsMap = new HashMap<Object, Object>();
dsMap.put("readDb", readDb());
dsMap.put("writeDb", writeDb());
dynamicDataSource.setTargetDataSources(dsMap);
return dynamicDataSource;
}
/**
* 配置@Transactional注解事物
* @return
*/
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dynamicDataSource());
}
}
4.数据源切换读取类
package com.yudu.db.config;
public class DataSourceContextHolder {
/**
* 默认数据源
*/
public static final String DEFAULT_DS = "readDb";
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
// 设置数据源名
public static void setDB(String dbType) {
//System.out.println("切换到{"+dbType+"}数据源");
contextHolder.set(dbType);
}
// 获取数据源名
public static String getDB() {
return (contextHolder.get());
}
// 清除数据源名
public static void clearDB() {
contextHolder.remove();
}
}
5.注解类(注意:要和配置类放在同一个包下,否则会抛出找不到注解异常)
package com.yudu.db.config;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface DS {
String value() default "readDb";
}
6.动态数据源(设置数据源自动调用该类方法)
package com.yudu.db.config;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
//System.out.println("数据源为"+DataSourceContextHolder.getDB());
return DataSourceContextHolder.getDB();
}
}
7.AOP
package com.yudu.db.config;
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.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Component
public class DynamicDataSourceAspect {
@Before("@annotation(DS)")
@SuppressWarnings("rawtypes")
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(DS.class)) {
DS annotation = method.getAnnotation(DS.class);
// 取出注解中的数据源名
dataSource = annotation.value();
}
} catch (Exception e) {
e.printStackTrace();
}
// 切换数据源
DataSourceContextHolder.setDB(dataSource);
}
@After("@annotation(DS)")
public void afterSwitchDS(JoinPoint point){
DataSourceContextHolder.clearDB();
}
}
8.repository
package com.yudu.db.repository;
import com.yudu.db.pojo.XtFile;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface XtFileRepository {
@Select("select * from XT_FILE where ID = #{id}")
@Results({
@Result(property = "id", column = "ID"),
@Result(property = "bid", column = "BID"),
@Result(property = "name", column = "NAME"),
@Result(property = "attachId", column = "ATTACHID"),
@Result(property = "path", column = "PATH"),
@Result(property = "fileType", column = "FILE_TYPE"),
@Result(property = "fileSize", column = "FILE_SIZE"),
@Result(property = "memo", column = "MEMO"),
@Result(property = "upLoadTime", column = "UPLOAD_TIME"),
@Result(property = "uploadStepId", column = "UPLOAD_STEPID"),
@Result(property = "uploadUserName", column = "UPDATED_USERNAME"),
@Result(property = "uploadUserId", column = "UPDATED_USERID"),
@Result(property = "fileSort", column = "FILE_SORT"),
@Result(property = "state", column = "STATE"),
@Result(property = "version", column = "VERSION"),
@Result(property = "data", column = "DATA"),
@Result(property = "transferId", column = "TRANSFERID"),
@Result(property = "noticeId", column = "NOTICEID"),
@Result(property = "draftType", column = "DRAFT_TYPE"),
})
XtFile selectById(String id);
}
9.serviceImpl
package com.yudu.db.service.impl;
import com.yudu.db.config.DS;
import com.yudu.db.pojo.XtFile;
import com.yudu.db.repository.XtFileRepository;
import com.yudu.db.service.XtFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class XtFileServiceImpl implements XtFileService {
@Autowired
private XtFileRepository xtFileRepository;
@Override
@DS("readDb")
public XtFile selectById(String id) {
return xtFileRepository.selectById(id);
}
@Override
@DS("writeDb")
public XtFile getById(String id) {
return xtFileRepository.selectById(id);
}
}
10.单元测试
package com.yudu.db;
import com.yudu.db.config.DS;
import com.yudu.db.pojo.XtFile;
import com.yudu.db.repository.XtFileRepository;
import com.yudu.db.service.XtFileService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class DbTest {
@Autowired
private XtFileService xtFileService;
@Test
public void test(){
XtFile m_xtFile = xtFileService.selectById("14FA331700F74EB29BA75499FFC41251");
String m_name = m_xtFile.getName();
System.out.println(m_name);
XtFile s_xtFile = xtFileService.getById("14FA331700F74EB29BA75499FFC41251");
String s_name = s_xtFile.getName();
System.out.println(s_name);
}
}
网友评论