Spring Boot 통합 Mybatis 구현 주종(다 중 데이터 원본)분리 방안 예시
11353 단어 springboot다 중 데이터 원본
Maven 프로젝트 를 새로 만 듭 니 다.최종 프로젝트 구 조 는 다음 과 같 습 니 다.
다 중 데이터 원본 을 sqlSession Factory 에 주입 합 니 다.
POM 은 다음 과 같은 의존 도 를 증가 시 킵 니 다.
<!--JSON-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.11</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<!--mapper-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>1.1.0</version>
</dependency>
<!--pagehelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.1.0</version>
<exclusions>
<exclusion>
<artifactId>mybatis-spring-boot-starter</artifactId>
<groupId>org.mybatis.spring.boot</groupId>
</exclusion>
</exclusions>
</dependency>
여기 서 주의해 야 할 것 은 프로젝트 는 my batis-spring-boot-starter 의 org.my batis.spring.boot.autoconfigure.Mybatis AutoConfiguration 을 확장 하여 다 중 데이터 원본 주입 을 실현 하 는 것 입 니 다.mybatis-spring-boot-starter:1.2.0 에서 이 클래스 는 기본 구조 함 수 를 취 소 했 기 때문에 이 프로젝트 는 1.1.0 버 전 을 사용 합 니 다.후속 버 전이 확장 개방 처 리 를 다시 할 지 주목 해 야 합 니 다.여전히 낡은 방안 을 사용 하 는 이 유 는 개인 적 으로 개방 확장 이 합 리 적 이 라 고 생각 하기 때문에 미래의 버 전에 서 돌아 올 것 이 라 고 믿 습 니 다.
다른 방안 이 필요 하 다 면 참고 하 세 요.
홈 라 이브 러 리 설정 추가(application.yml)
druid:
type: com.alibaba.druid.pool.DruidDataSource
master:
url: jdbc:mysql://192.168.249.128:3307/db-test?characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useUnicode=true
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
initial-size: 5
min-idle: 1
max-active: 100
test-on-borrow: true
slave:
url: jdbc:mysql://192.168.249.128:3317/db-test?characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
initial-size: 5
min-idle: 1
max-active: 100
test-on-borrow: true
데이터 원본 만 들 기
@Configuration
@EnableTransactionManagement
public class DataSourceConfiguration {
@Value("${druid.type}")
private Class<? extends DataSource> dataSourceType;
@Bean(name = "masterDataSource")
@Primary
@ConfigurationProperties(prefix = "druid.master")
public DataSource masterDataSource(){
return DataSourceBuilder.create().type(dataSourceType).build();
}
@Bean(name = "slaveDataSource")
@ConfigurationProperties(prefix = "druid.slave")
public DataSource slaveDataSource1(){
return DataSourceBuilder.create().type(dataSourceType).build();
}
}
다 중 데이터 원본 을 sqlSession Factory 에 주입 합 니 다.앞에서 언급 한 바 와 같이 mybatis-spring-boot-starter 를 확장 하 는 org.mybatis.spring.boot.autoconfigure.Mybatis AutoConfiguration 을 통 해 다 중 데이터 원본 주입 을 실현 합 니 다
@Configuration
@AutoConfigureAfter({DataSourceConfiguration.class})
public class MybatisConfiguration extends MybatisAutoConfiguration {
private static Log logger = LogFactory.getLog(MybatisConfiguration.class);
@Resource(name = "masterDataSource")
private DataSource masterDataSource;
@Resource(name = "slaveDataSource")
private DataSource slaveDataSource;
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
return super.sqlSessionFactory(roundRobinDataSouceProxy());
}
public AbstractRoutingDataSource roundRobinDataSouceProxy(){
ReadWriteSplitRoutingDataSource proxy = new ReadWriteSplitRoutingDataSource();
Map<Object,Object> targetDataResources = new ClassLoaderRepository.SoftHashMap();
targetDataResources.put(DbContextHolder.DbType.MASTER,masterDataSource);
targetDataResources.put(DbContextHolder.DbType.SLAVE,slaveDataSource);
proxy.setDefaultTargetDataSource(masterDataSource);//
proxy.setTargetDataSources(targetDataResources);
return proxy;
}
}
읽 기와 쓰기 분리 실현(다 중 데이터 원본 분리)여기 서 주요 한 사고방식 은 다음 과 같다.
1-서로 다른 데이터 소스 표 지 를 ThreadLocal 에 기록 합 니 다.
2-현재 service 방법 으로 어떤 라 이브 러 리 를 사용 하 는 지 설명 을 통 해 표시 합 니 다.
3-Spring AOP 를 통 해 차단 주 해 를 실현 하고 서로 다른 표 지 를 threadlocal 에 주입 합 니 다.
4-원본 을 가 져 올 때 threadlocal 의 서로 다른 표 지 를 통 해 서로 다른 sqlSession 을 제공 합 니 다.
표지 저장 ThreadLocal 의 실현
public class DbContextHolder {
public enum DbType{
MASTER,SLAVE
}
private static final ThreadLocal<DbType> contextHolder = new ThreadLocal<>();
public static void setDbType(DbType dbType){
if(dbType==null)throw new NullPointerException();
contextHolder.set(dbType);
}
public static DbType getDbType(){
return contextHolder.get()==null?DbType.MASTER:contextHolder.get();
}
public static void clearDbType(){
contextHolder.remove();
}
}
주해 실현
/**
* service , slaves
* Created by Jason on 2017/3/6.
*/
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ReadOnlyConnection {
}
Spring AOP 의 주해 차단
@Aspect
@Component
public class ReadOnlyConnectionInterceptor implements Ordered {
public static final Logger logger = LoggerFactory.getLogger(ReadOnlyConnectionInterceptor.class);
@Around("@annotation(readOnlyConnection)")
public Object proceed(ProceedingJoinPoint proceedingJoinPoint,ReadOnlyConnection readOnlyConnection) throws Throwable {
try {
logger.info("set database connection to read only");
DbContextHolder.setDbType(DbContextHolder.DbType.SLAVE);
Object result = proceedingJoinPoint.proceed();
return result;
}finally {
DbContextHolder.clearDbType();
logger.info("restore database connection");
}
}
@Override
public int getOrder() {
return 0;
}
}
표지 에 따라 다른 소스 를 얻 습 니 다.여기 서 우 리 는 AbstractRouting DataSource 를 확장 하여 서로 다른 소스 를 얻 습 니 다.이것 은 Spring 이 제공 하 는 사용자 의 요청 에 따라 서로 다른 데이터 원본 을 변환 할 수 있 습 니 다.예 를 들 어 사용자 의 지역 언어 에 따라 서로 다른 데이터 베 이 스 를 선택 할 수 있 습 니 다.원본 코드 를 보면 determineCurrentLookupkey()를 통 해 돌아 오 는 서로 다른 key 를 통 해 sqlSession Factory 에 다른 소스 를 가 져 오 는 것 을 알 수 있 습 니 다.(앞에서 sqlSession Factory 에 여러 개의 소스 를 주입 하 는 방법 을 보 여 주 었 습 니 다)
public class ReadWriteSplitRoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DbContextHolder.getDbType();
}
}
읽 기와 쓰기 분리(다 중 데이터 원본)설정 이 완료 되 었 습 니 다.다음은 구체 적 인 실례 이다사용 방식
Entity
@Table(name = "t_sys_dic_type")
public class DicType extends BaseEntity{
String code;
String name;
Integer status;
...
}
Mapper
public interface DicTypeMapper extends BaseMapper<DicType> {
}
Service
@Service
public class DicTypeService {
@Autowired
private DicTypeMapper dicTypeMapper;
@ReadOnlyConnection
public List<DicType> getAll(DicType dicType){
if (dicType.getPage() != null && dicType.getRows() != null) {
PageHelper.startPage(dicType.getPage(), dicType.getRows());
}
return dicTypeMapper.selectAll();
}
}
여기@ReadOnly Connection 주석 주의Controller
@RestController
@RequestMapping("/dictype")
public class DicTypeController {
@Autowired
private DicTypeService dicTypeService;
@RequestMapping(value = "/all")
public PageInfo<DicType> getALL(DicType dicType){
List<DicType> dicTypeList = dicTypeService.getAll(dicType);
return new PageInfo<>(dicTypeList);
}
}
mvn spring-boot:run 을 통 해 시작 하면 통과 할 수 있 습 니 다.http://localhost:9090/dictype/all 데이터 가 져 오기배경 인쇄
c.a.d.m.ReadOnlyConnectionInterceptor : set database connection to read only
라 이브 러 리 링크 에서 데 이 터 를 가 져 왔 음 을 설명 합 니 다.비고:다 원 사 무 를 어떻게 보장 합 니까?
1-읽 기와 쓰기 분리 장면 에서 주종 라 이브 러 리 업 무 를 고려 하지 않 고 순 독 된 상하 문 에@ReadOnly Connection 탭 을 사용 합 니 다.다른 것 은 기본 라 이브 러 리 를 사용 합 니 다.
2-다 원 장면 에서 Spring 의@Transaction 은 다 원 의 사무 성 을 확보 할 수 있 습 니 다.
전송 문
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.