최근에, 나는 마진 밸런스 쿼리 최적화를하고 있습니다. 프로젝트가 시작되면 모든 라이더의 여백 균형을 완전히 쿼리해야하기 때문에 균형을 로컬 캐시에 완전히로드해야합니다. 기본 데이터베이스의 성능에 영향을 미치지 않으려면 쿼리를 남겨 두십시오. 따라서 프로젝트에서 여러 데이터 소스를 구성하고 동적으로 전환 할 수 있어야합니다. 일부 탐색 후, 동적 스위칭이 완벽하게 실현되고 구성 방법이 참조를 위해 기록됩니다.
전반적인 디자인 아이디어
Spring-Boot+AOP Method는 멀티 데이터 소스 스위칭을 실현하고, AbstractroutingDatasource를 상속하여 동적 데이터 소스 획득을 달성하고, 서비스 계층에서 주석을 사용하여 데이터 소스를 지정합니다.
단계
1. 다중 데이터 소스 구성
application.properties에서 우리의 구성은 다음과 같습니다
#master 데이터 소스 druid.master.url = jdbc : mysql : // url/mas id.mas 1#데이터 소스에서 druid.slave.url = jdbc : mysql : // url/slailedb? useUnicode = true & charac id.slave.driver-class-name = com.mysql.jdbc.driverdruid.slave.max-wait = 5000druid.slave.max-active = 100druid.slave.test-on-borrow = truedruid.slave.validation-query = select 1
구성을 읽으십시오
<!-마스터 데이터 소스-> <bean primary = "true"id = "mas 이름 = "username"value = "$ {druid.mas 이름 = "maxwait"value = "$ {druid.mas id = "slavedb"init-method = "init"destroy-method = "close"> <!-기본 속성 URL, 사용자, 비밀번호-> <속성 이름 = "driverclassName"value = "com.mysql.jdbc.driver"/> <속성 이름 = "url"value = "$ {druid.slave.url}"/> <property name = "userame" value = "$ {druid.slave.username}"/> <property name = "password"value = "$ {druid.slave.password}"/> <!-초기화 크기, 최소 및 최대-> <속성 이름 = "maxactive"value = "$ {druid.slave.max-Active}"! <property name = "maxwait"value = "$ {druid.slave.max-wait}"/> <property name = "validationQuery"value = "$ {druid.slave.validation-query}"/> <property name = "testonbrous"value = "$ {druid.slave.test-on-borrous}"/> </bean ronge gloat} "/> 서비스 인터페이스의 주석을 기반으로하려면-> <bean id = "dataSource"> <property name = "targetdatasources"> <map key-type = "java.lang.string"> <Entry Key = "realth"value-ref = "slaveedb"/> <enther key = "master"value-ref = "masterdb" 이름 = "defaultTargetDatasource"ref = "mas /> </bean>> <bean id = "transactiontemplate"> <속성 이름 = "transactionManager"ref = "TransactionManager"/> </bean> <tx : 주석 구동 트랜잭션-매너 = "transactionManager"proxy-target class = "true"order = "2"/> <!-restalsdbsqlsessionfactory-> <id id = "sqlseticessionsongedsqlsessionfactory-> 이름 = "dataSource"ref = "dataSource"/> <속성 이름 = "mapperlocations"value = "classPath*: mapper-xxdb/*mapper*.xml"/> </bean> <ean> <속성 이름 = "basepackage"value = "xxdb.mapper"/> value = "sqlsessionfactory"/> </bean>2. 동적 데이터 소스
Spring은 라우팅이있는 데이터 소스 인 AbstractroutingDatasource를 제공합니다. 상속 후 실제 데이터 소스 이름의 라우팅 메소드를 사용자 정의하는 데 사용되는 DecineCurrentLookupKey ()를 구현해야합니다. 우리는 정보를 ThreadLocal에 저장하므로 정보를 꺼내면됩니다.
Public Class DynamicDatasource는 AbsTractroutingDatasource를 확장합니다. @override Protected Object DeciNeCurrentLookUpkey () {String DataSource = jdbccontexTholder.getDatasource (); logger.info ( "데이터 소스는 {}", DataSource); 반환 데이터 소스; }}3. 동적 스위칭 클래스 데이터 소스
동적 데이터 소스 스위칭은 AOP를 기반으로하므로 AOP 섹션을 선언하고 섹션 앞에서 데이터 소스 스위칭을 수행해야합니다. 섹션이 완료되면 데이터 소스 이름이 제거됩니다.
@SALSE @Order (1) // AOP 실행 순서를 설정합니다 (트랜잭션 전에 필요합니다. 그렇지 않으면 트랜잭션은 기본 라이브러리에서만 발생합니다) @ComponentPublic Class DataSourCeaspect {private logger = loggerfactory.getLogger (this.getClass ()); // 컷 포인트 @PointCut ( "execution (*com.xxx.service.*.*(..))") public void species () {} @before ( "agage ()") private void ~ (joinpoint point) {object target = point.getTarget (); 문자열 메소드 = point.getSignature (). getName (); class <?> classz = target.getClass (); // 대상 클래스 클래스를 가져옵니다 <?> [] parametertypes = ((메소드 디자너) point.getSignature ()) .getMethod (). getParameterTypes (); try {method m = classz.getMethod (메소드, ParameterTypes); if (m! = null && m.isannotationpresent (mydatasource.class)) {mydatasource data = m.getannotation (mydatasource.class); logger.info ( "method : {}, dataSource : {}", m.getName (), data.value (). getName ()); JDBCCONTEXTHOLDER.PUTDATASORCE (data.Value (). getName ()); // 데이터 소스를 현재 스레드에 넣습니다}} catch (예외 e) {logger.error ( "get dataSource error", e); // mas }}4. 데이터 소스 관리 범주
공개 클래스 JDBCCONTEXTHOLDER {Private Final STATIC ThreadLocal <string> local = New ThreadLocal <> (); public static void putdatasource (문자열 이름) {local.set (name); } public static String getDatasource () {return local.get (); } public static void cleardatasource () {local.remove (); }}5. 데이터 소스 주석 및 열거
데이터 소스를 전환 할 때 일반적으로 특정 인터페이스의 메소드를 호출하기 전에 데이터 소스를 구현하므로 메소드 주석을 정의합니다. AOP가 메소드에 주석이 존재 함을 감지하면 주석의 값에 해당하는 이름에 따라 전환됩니다.
@retention (rendentionpolicy.runtime) @target (elementtype.method) public @interface mydatasource {dataSourcetype value ();} public enum dataSourcetype {// master ( "master"), // 슬레이브 ( "슬레이브"); 개인 문자열 이름; private dataSourceType (문자열 이름) {this.name = name; } public String getName () {return name; } public void setName (문자열 이름) {this.name = 이름; }}6. 포인트 주석을 잘라냅니다
동적 데이터 소스에는 기본 라이브러리가 있으므로 메소드가 기본 라이브러리를 작동하는 경우 주석이 필요하지 않습니다. 비 디폴트 데이터 소스를 작동하려면 메소드에 @MyDatasource ( "DataSource Name") 주석을 추가하여 AOP를 사용하여 동적 스위칭을 달성 할 수 있도록해야합니다.
@ComponentPublic 클래스 xxxserviceimpl {@Resource private XXXMAPPEREXT XXXMAPPEREXT; @MyDatAsource (value = dataSourcetype.slave) public list <bood> getall () {return xxxmapperext.getall (); }}위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.