1.추상 적 인 라 우 팅 데이터 소스 추상 적 인 소스 코드 분석
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource 이하 변수 주목
@Nullable
private Map<Object, Object> targetDataSources; //
@Nullable
private Object defaultTargetDataSource; //
@Nullable
private Map<Object, DataSource> resolvedDataSources; //
@Nullable
private DataSource resolvedDefaultDataSource; //
이 두 그룹의 변 수 는 서로 대응 하 는 것 입 니 다.여러 개의 인 스 턴 스 데이터 소스 전환 코드 를 잘 알 고 있 을 때 여러 개의 데이터 소스 가 있 을 때 기본 데이터 소스 로 지정 해 야 합 니 다.
여기 서도 마찬가지 입 니 다.여러 데이터 원본 을 동시에 초기 화 할 때 setDefault TargetDataSource 방법 을 기본 데이터 원본 으로 지정 해 야 합 니 다.
우리 가 주목 해 야 할 것 은 맵
targetDataSources 와 맵resolvedDataSources 입 니 다. targetDataSources 는 외부 프로그램 에 노출 되 어 값 을 부여 하 는 것 이 고 resolvedDataSources 는 프로그램 내부 에서 실 행 될 때의 근거 이기 때문에 값 을 부여 하 는 작업 이 있 을 수 있 습 니 다. 이 소스 코드 를 통 해 알 수 있 듯 이 실행 할 때마다 targetDataSources 안의 모든 요 소 를 옮 겨 다 니 며 resolvedDataSources 에 값 을 부여 합 니 다.이렇게 하면 외부 프로그램 에 새로운 데이터 원본 을 추가 하면 내부 에 추가 하여 사용 하여 데이터 원본 의 동적 로드 를 실현 합 니 다. 이 추상 류 를 계승 할 때 추상 적 인 방법 을 실현 해 야 합 니 다.proctected abstract Object determineCurrentLookupkey().이 방법 은 어떤 데이터 원본 을 사용 해 야 하 는 지 지정 하 는 데 사 용 됩 니 다. 2.다 중 데이터 소스 전환 과 동적 데이터 소스 로드 실현 A-프로필 정보 application.yml 파일
server:
port: 18080
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
#
master-db:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.223.129:13306/test_master_db?characterEncoding=utf-8
username: josen
password: josen
#
slave-db:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.223.129:13306/test_slave_db?characterEncoding=utf-8
username: josen
password: josen
mybatis:
mapper-locations: classpath:mapper/*.xml
logging:
path: ./logs/mydemo20201105.log
level:
com.josen.mydemo20201105: debug
maven 의존
<dependencies>
<!-- AOP -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
B-코딩 실현 1.DynamicDataSource 류 를 만 들 고 AbstractRoutingDataSource 추상 류 를 계승 하여 determineCurrentLookupkey 방법 을 실현 합 니 다.이 방법 을 통 해 현재 사용 하고 있 는 데이터 원본 을 지정 합 니 다. 2.DynamicDataSource 클래스 에서 ThreadLocal 을 통 해 전체 데이터 원본 이름 을 유지 하고 나중에 이 이름 을 수정 하여 동적 전환 을 실현 합 니 다.
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import javax.sql.DataSource;
import java.util.Map;
/**
* @ClassName DynamicDataSource
* @Description
* @Author Josen
* @Date 2020/11/5 14:28
**/
public class DynamicDataSource extends AbstractRoutingDataSource {
// ThreadLocal map
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
/**
*
*/
@Override
protected Object determineCurrentLookupKey() {
return getDataSource();
}
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
public static String getDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
}
3.DynamicDataSourceConfig 류 를 만 들 고 application.yaml 설정 의 여러 데이터 소스 정 보 를 도입 하여 여러 데이터 소스 를 구축 합 니 다.
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* @ClassName DynamicDataSourceConfig
* @Description ,
* @Author Josen
* @Date 2020/11/5 14:23
**/
@Configuration
@Component
public class DynamicDataSourceConfig {
/**
* application , master-db
*/
@Bean
@ConfigurationProperties("spring.datasource.druid.master-db")
public DataSource myMasterDataSource(){
return DruidDataSourceBuilder.create().build();
}
/**
* application , slave-db
*/
@Bean
@ConfigurationProperties("spring.datasource.druid.slave-db")
public DataSource mySlaveDataSource(){
return DruidDataSourceBuilder.create().build();
}
/**
* application ,
*/
@Bean
@Primary
public DynamicDataSource dataSource(DataSource myMasterDataSource, DataSource mySlaveDataSource) {
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("master-db",myMasterDataSource);
targetDataSources.put("slave-db", mySlaveDataSource);
// myMasterDataSource=
// targetDataSources= ( )
return new DynamicDataSource(myMasterDataSource, targetDataSources);
}
}
4.MyDataSource 사용자 정의 주 해 를 만 들 고 후속 AOP 는 이 주 해 를 착안점 으로 하고 이 주 해 를 사용 하여 서로 다른 값 을 동적 으로 지정 한 데이터 원본 으로 전환 합 니 다.
import java.lang.annotation.*;
/**
*
* Service ,
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyDataSource {
String name() default "";
}
5.DataSourceAspectAOP 절단면 류 를 만 들 고 MyDataSource 주 해 를 착안점 으로 확대 합 니 다.@MyDataSource 에 의 해 주석 이 들 어 오 는 방법 을 실행 할 때 이 주석 이 들 어 오 는 name 을 가 져 오고 지정 한 데이터 원본 으로 전환 하여 실행 합 니 다.실행 이 완료 되면 기본 데이터 원본 으로 전환 합 니 다.
import com.josen.mydemo20201105.annotation.MyDataSource;
import com.josen.mydemo20201105.datasource.DynamicDataSource;
import lombok.extern.slf4j.Slf4j;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.lang.reflect.Method;
/**
* @ClassName DataSourceAspect
* @Description Aop
* @Author Josen
* @Date 2020/11/5 14:35
**/
@Aspect
@Component
@Slf4j
public class DataSourceAspect {
private static final Logger logger = LoggerFactory.getLogger(DataSourceAspect.class);
/**
*
* @MyDataSource around
*/
@Pointcut("@annotation(com.josen.mydemo20201105.annotation.MyDataSource)")
public void dataSourcePointCut() {
}
/**
* MyDataSource ,
* : ( & & & ) ,
* @param point
*/
@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
logger.info("execute DataSourceAspect around=========>"+method.getName());
// 1. MyDataSource,
MyDataSource dataSource = method.getAnnotation(MyDataSource.class);
if(dataSource == null){
// 1.1
DynamicDataSource.setDataSource("master-db");
}else {
// 1.2
DynamicDataSource.setDataSource(dataSource.name());
logger.info(" =========>"+dataSource.name());
}
try {
return point.proceed();
} finally {
// -
DynamicDataSource.clearDataSource();
}
}
}
6.시작 클래스 설정
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class}) //
@MapperScan(basePackages = "com.josen.mydemo.mapper")
public class MydemoApplication {
public static void main(String[] args) {
SpringApplication.run(MydemoApplication.class, args);
}
}
7.여기까지 기본적으로 완성 되 었 고 나머지 는 데이터 원본 을 정확하게 전환 하 는 지 테스트 하 는 것 입 니 다. Mapper 층
@Repository
public interface PermissionMapper {
List<Permission> findAll();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.josen.mydemo.mapper.PermissionMapper">
<select id="findAll" resultType="com.josen.mydemo20201105.pojo.Permission">
select * from t_permission;
</select>
</mapper>
서비스 층
@Service
public class PermissionService {
@Autowired
private PermissionMapper permissionMapper;
//
@MyDataSource(name = "slave-db")
public List<Permission> findSlaveAll(){
return permissionMapper.findAll();
}
//
public List<Permission> findAll(){
return permissionMapper.findAll();
}
}
컨트롤 러 층
@RestController
@RequestMapping("/permission")
public class PermissionController {
@Autowired
private PermissionService permissionService;
// master-db
@GetMapping("/master")
public List<Permission> handlerFindAll() {
List<Permission> list = permissionService.findAll();
return list;
}
// slave-db
@GetMapping("/slave")
public List<Permission> handlerFindAll2() {
List<Permission> list = permissionService.findSlaveAll();
return list;
}
}
C-테스트 데이터 원본 전환 Mysql 데이터 인터페이스 반환 데이터 데모 소스 주소:https://gitee.com/taco-gigigi/multiple-data-sources 총결산 Springboot 프로젝트 가 Mysql 다 중 데이터 원본 전환 을 실현 하 는 것 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 Springboot 프로젝트 Mysql 다 중 데이터 원본 전환 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 지원 바 랍 니 다!
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin Springboot -- 파트 14 사용 사례 REST로 전환하여 POST로 JSON으로 전환
前回 前回 前回 記事 の は は で で で で で で を 使っ 使っ 使っ て て て て て リクエスト を を 受け取り 、 reqeustbody で 、 その リクエスト の ボディ ボディ を を 受け取り 、 関数 内部 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.