The record about the configuration process java development of multiple data sources,
Reference blog: https://blog.csdn.net/weinichendian/article/details/72903757 , I'm here were consolidated, excluding the content inside the springboot2.0 error, and did not say too well inside the content were Detailed explanation
1. Profiles application.yml
personnel:#数据源1 driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3307/person?useSSL=false&useUnicode=true&characterEncoding=utf8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&allowMultiQueries=true&allowPublicKeyRetrieval=true username: root password: ******* userauth:#数据源2 driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3307/user?useSSL=false&useUnicode=true&characterEncoding=utf8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&allowMultiQueries=true&allowPublicKeyRetrieval=true username: root password: ******
2. different data sources enumeration:
public enum DataSourceEnum {master,slaver;}
3. enum class tool set
public class DataSourceContextHolder { private static final ThreadLocal<DataSourceEnum> CONTEXT_HOLDER = new ThreadLocal<DataSourceEnum>() { @Override protected DataSourceEnum initialValue() { return DataSourceEnum.master; } }; public static void setDataSourceType(DataSourceEnum type) { CONTEXT_HOLDER.set(type); } public static DataSourceEnum getDataSourceType() { return CONTEXT_HOLDER.get(); } public static void resetDataSourceType() { CONTEXT_HOLDER.set(DataSourceEnum.master); } }
4. custom annotation
@Retention (RetentionPolicy.RUNTIME) // at runtime visible @Target (ElementType.METHOD) // annotation method can be used on public @ interface DataSourceTypeAnno {// Add the use of the method on the service layer @DataSourceTypeAnno (DataSourceEnum. Data Source enumerated type) that the data source is used
DataSourceEnum value() default DataSourceEnum.master; }
5.aop interception: here the use of asp
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.core.annotation.Order; import org.springframework.stereotype.Component; import java.lang.reflect.Method; @Component @Aspect @Order(-100)//为了保证可以拦截到 public class DataSourceAspect { @Pointcut("execution (* com.yzy. *. * .. * (..))" + // tangent point where scanning is mainly packet service layer, a method according to the upper layer of said service custom annotations, to Analyzing the data source type is used, and dynamically switching the data source "&& @annotation (com.yzy.config.DataSourceTypeAnno)" ) public void dataSourcePointcut () { } @Around ( "dataSourcePointcut ()" ) public Object doAround (PJP ProceedingJoinPoint ) { MethodSignature MethodSignature = (MethodSignature) pjp.getSignature (); Method, Method = methodSignature.getMethod (); DataSourceTypeAnno typeAnno . = method.getAnnotation (DataSourceTypeAnno class ); DataSourceEnum sourceEnum= typeAnno.value(); if (sourceEnum == DataSourceEnum.master) { DataSourceContextHolder.setDataSourceType(DataSourceEnum.master); } else if (sourceEnum == DataSourceEnum.slaver) { DataSourceContextHolder.setDataSourceType(DataSourceEnum.slaver); } Object result = null; try { result = pjp.proceed(); } catch (Throwable throwable) { throwable.printStackTrace(); } finally { DataSourceContextHolder.resetDataSourceType(); } return result; } }
6. Configuration mybatisConfig = "data source information
Import org.apache.ibatis.session.SqlSessionFactory; Import org.mybatis.spring.SqlSessionFactoryBean; Import org.mybatis.spring.annotation.MapperScan; Import org.springframework.beans.factory.annotation.Qualifier; Import the org.springframework.beans .factory.annotation.Value; Import org.springframework.boot.jdbc.DataSourceBuilder; // org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; the package is replaced in springboot2.0, we are currently online this springboot1.5 package, it will have been an error Import org.springframework.boot.context.properties.ConfigurationProperties; Import org.springframework.context.annotation.Bean; Importorg.springframework.context.annotation.Configuration; Import org.springframework.context.annotation.Primary; Import org.springframework.core.io.support.PathMatchingResourcePatternResolver; Import org.springframework.jdbc.datasource.DataSourceTransactionManager; Import the javax.sql. the DataSource; Import the java.util.HashMap; Import a java.util.Map; @Configuration @MapperScan (basePackages =. ". * com.yzy mapper" ) // scan dao layer mapper interfaces public class MyBatisConfig { / ** * @return * @throws Exception * @Primary must specify one and only one primary data source, otherwise an error * / @Primary @Bean ( "masterDataSource" ) @ConfigurationProperties (prefix = "spring.datasource.userauth" ) // prefix based on the data source to the data source information read application.yml // This change can change the default prefix data source // public the dataSource masterDataSource () throws Exception { return DataSourceBuilder.create () Build ();. } @Bean ( "slaverDataSource" ) @ConfigurationProperties (prefix = "spring.datasource.personnel" ) // prefix to the application based on the data source // read the data source information .yml can configure the data source, is provided to the application. yml present, but also need to add the enumerated type enumeration class public the DataSource slaverDataSource () throws Exception { return . DataSourceBuilder.create () Build (); } / ** * @Qualifier implanting by name, usually having a plurality of injection instances of the same type (e.g., multiple instances of type DataSource) * @DataSourceTypeAnno (DataSourceEnum.master) transaction method to specify the data source * / @Bean ( "dynamicDataSource" ) public dynamicDataSource dynamicDataSource (@Qualifier ( "masterDataSource" ) the dataSource masterDataSource, @Qualifier ( "slaverDataSource" ) the dataSource slaverDataSource) { the Map <Object, Object > = targetDataSources new new the HashMap <Object, Object> (); targetDataSources.put (DataSourceEnum.master, masterDataSource); targetDataSources.put (DataSourceEnum.slaver, slaverDataSource); DynamicDataSource the dataSource = new new DynamicDataSource (); dataSource.setTargetDataSources (targetDataSources); // This method is a method AbstractRoutingDataSource dataSource.setDefaultTargetDataSource (masterDataSource ); // default setting datasource myTestDbDataSource return the dataSource; } / ** * Create data source SqlSessionFactory * / @Bean public SqlSessionFactory SqlSessionFactory (@Qualifier ( "dynamicDataSource") DynamicDataSource dynamicDataSource, @Value ( "Package-mybatis.type-aliases") String typeAliasesPackage) throws Exception { the SqlSessionFactoryBean FactoryBean = new new the SqlSessionFactoryBean (); factoryBean.setDataSource (dynamicDataSource); // the specified data source (this must, otherwise an error ) // below for only two * .xml file, if the entire operation without the use of the persistence xml file if (can get only with annotations), plus no factoryBean.setTypeAliasesPackage (typeAliasesPackage); // specified entity class package is located factoryBean.setMapperLocations ( new new PathMatchingResourcePatternResolver () getResources (. "the CLASSPATH: Mapping / ** / * Mapper.xml")); // package scanning mapper.xml return FactoryBean.getObject (); } / ** * Configuration transaction manager * / @Bean public DataSourceTransactionManager the transactionManager (DynamicDataSource the dataSource) throws Exception { return new new DataSourceTransactionManager (the dataSource); } }