美文网首页
springboot datajpa 多数据库主从分离代码实现

springboot datajpa 多数据库主从分离代码实现

作者: anyangdp | 来源:发表于2018-03-23 15:17 被阅读158次

    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.springboot</groupId>
        <artifactId>springboot-muti-dataSource</artifactId>
        <version>1.0-SNAPSHOT</version>
    
    <!---https://github.com/anyangdp/anyangdp-frame(datajpa集成,clone到本地打包使用,长期更新,麻烦star谢谢。)--->
        <parent>
            <groupId>com.anyangdp</groupId>
            <artifactId>anyangdp-parent</artifactId>
            <version>1.0.0</version>
        </parent>
    
        <properties>
            <java.compile.version>1.8</java.compile.version>
    
            <!-- Maven plugin -->
            <maven.compiler.plugin.version>3.2</maven.compiler.plugin.version>
            <maven-surefire-plugin.version>2.18.1</maven-surefire-plugin.version>
            <maven-source-plugin.version>2.4</maven-source-plugin.version>
            <maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
            <maven-release-plugin.version>2.5.1</maven-release-plugin.version>
            <flyway-maven-plugin.version>4.1.1</flyway-maven-plugin.version>
        </properties>
    
        <dependencies>
    
            <dependency>
                <groupId>com.anyangdp</groupId>
                <artifactId>common-jpa-biz</artifactId>
                <version>1.0.0</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jdbc</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <optional>true</optional>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
    
        </dependencies>
    
    
    </project>
    

    application.properties:

    ### master
    spring.datasource.url=jdbc:mysql://localhost:3306/master?serverTimezone=UTC&characterEncoding=utf-8&useSSL=false
    spring.datasource.username=
    spring.datasource.password=
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    
    ### cluster
    cluster.datasource.url=jdbc:mysql://localhost:3307/slaver?useUnicode=true&characterEncoding=utf8
    cluster.datasource.username=
    cluster.datasource.password=
    cluster.datasource.driverClassName=com.mysql.jdbc.Driver
    

    相关java代码

    /**
     * @Author anyang
     * @CreateTime 2018/3/23
     * @Des 数据源配置
     */
    @Configuration
    public class DataSourceConfiguration {
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource")
        public DataSource masterDataSource() {
            return DataSourceBuilder.create().build();
        }
    
        @Bean
        @ConfigurationProperties(prefix = "cluster.datasource")
        public DataSource slaveDataSource() {
            return DataSourceBuilder.create().build();
        }
    
        @Bean
        public DataSource routeDataSource() {
            return new RoutingDataSource() {{
                setDefaultTargetDataSource(masterDataSource());
                setTargetDataSources(new HashMap<Object, Object>() {{
                    put(DataSourceType.MASTER, masterDataSource());
                    put(DataSourceType.SLAVE, slaveDataSource());
                }});
            }};
        }
    
        @Bean
        @Primary
        public LazyConnectionDataSourceProxy lazyConnectionDataSourceProxy() {
            return new LazyConnectionDataSourceProxy(routeDataSource());
        }
    }
    
    
    /**
     * @Author anyang
     * @CreateTime 2018/3/23
     * @Des 数据源获取,设置
     */
    public class DataSourceContextHolder {
        private static final ThreadLocal<DataSourceType> contextHolder = new ThreadLocal<DataSourceType>();
    
        public static void setDataSourceType(DataSourceType dataSourceType) {
            if(dataSourceType == null){
                throw new NullPointerException();
            }
            contextHolder.set(dataSourceType);
        }
    
        public static DataSourceType getDataSourceType() {
            return contextHolder.get();
        }
    
        public static void clearDataSourceType() {
            contextHolder.remove();
        }
    }
    
    /**
     * @Author anyang
     * @CreateTime 2018/3/23
     * @Des
     */
    public enum DataSourceType {
        MASTER,
        SLAVE
    }
    
    /**
     * @Author anyang
     * @CreateTime 2018/3/23
     * @Des 切点处理主从切换
     */
    @Slf4j
    @Aspect
    @Configuration
    public class DBConnectionAOP {
    
        private final String[] QUERY_PREFIX = {"find"};
    
    // || execution(* com.anyangdp..*.*(..))
        @Pointcut("execution(* com.cy.dao.*.*(..))")
        public void daoAspect() {
    
        }
    
        @Before("daoAspect()")
        public void switchDataSource(JoinPoint point) {
            Boolean isQueryMethod = isQueryMethod(point.getSignature().getName());
            if (isQueryMethod) {
                DataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE);
                log.info("Switch DataSource to [{}] in Method [{}]",
                        DataSourceContextHolder.getDataSourceType(), point.getSignature());
            } else {
                DataSourceContextHolder.setDataSourceType(DataSourceType.MASTER);
            }
        }
    
        private Boolean isQueryMethod(String methodName) {
            for (String prefix : QUERY_PREFIX) {
                if (methodName.startsWith(prefix)) {
                    return true;
                }
            }
            return false;
        }
    
    
    }
    
    /**
     * @Author anyang
     * @CreateTime 2018/3/23
     * @Des spring jdbc对于多数据源的处理,重写抽象接口
     */
    public class RoutingDataSource extends AbstractRoutingDataSource {
        @Override
        protected Object determineCurrentLookupKey() {
    
           if(DataSourceContextHolder.getDataSourceType() == DataSourceType.MASTER){
                return DataSourceType.MASTER;
            }
    
            return DataSourceType.SLAVE;
        }
    }
    
    
    @SpringBootApplication
    @EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class)###必须添加,禁用springboot自动注入datasource
    public class Application{
        
        public static void main(String[] args) throws Exception {
            SpringApplication.run(Application.class, args);
        }
    
    }
    
    

    相关文章

      网友评论

          本文标题:springboot datajpa 多数据库主从分离代码实现

          本文链接:https://www.haomeiwen.com/subject/fclxcftx.html