• Mybatis 读写分离简单实现


    package com.box.batisplus.db.source;

    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;

    @Slf4j
    @Aspect
    @Component
    public class DataSourceAspect {

    @Pointcut("!@annotation(com.box.batisplus.annotation.Master) " +
    "&& (execution(* com.box.*.service..*.select*(..)) " +
    "|| execution(* com.box.*.service..*.get*(..)))"+
    "|| execution(* com.baomidou.mybatisplus.extension.service..*.get*(..)))"+
    "|| execution(* com.baomidou.mybatisplus.extension.service..*.list*(..)))"+
    "|| execution(* com.baomidou.mybatisplus.extension.service..*.count*(..)))"+
    "|| execution(* com.baomidou.mybatisplus.extension.service..*.page*(..)))")
    public void readPointcut() {

    }

    @Pointcut("@annotation(com.box.batisplus.annotation.Master) " +
    "|| execution(* com.box.*.service..*.insert*(..)) " +
    "|| execution(* com.box.*.service..*.add*(..)) " +
    "|| execution(* com.box.*.service..*.save*(..)) " +
    "|| execution(* com.box.*.service..*.update*(..)) " +
    "|| execution(* com.box.*.service..*.edit*(..)) " +
    "|| execution(* com.box.*.service..*.delete*(..)) " +
    "|| execution(* com.box.*.service..*.remove*(..))" +
    "|| execution(* com.baomidou.mybatisplus.extension.service..*.remove*(..))" +
    "|| execution(* com.baomidou.mybatisplus.extension.service..*.update*(..))" +
    "|| execution(* com.baomidou.mybatisplus.extension.service..*.save*(..))")

    public void writePointcut() {

    }

    @Before("readPointcut()")
    public void read() {
    DBContextHolder.slave();
    }

    @Before("writePointcut()")
    public void write() {
    DBContextHolder.master();
    }



    @After("readPointcut()")
    public void destroy() {
    log.info("DataSourceAspect.destroy is db:{}",DBContextHolder.get());
    if(DBContextHolder.get() != null){
    DBContextHolder.remove();
    log.info("DataSourceAspect.destroy is db remove:{}",DBContextHolder.get());
    }

    }

    }


    package com.box.batisplus.config;

    /**
    * 数据源配置
    *
    * @author yuan.dingwang
    * @date 2021年03月30日 15:36
    */

    import com.box.batisplus.db.source.MyRoutingDataSource;
    import com.box.batisplus.enums.DBTypeEnum;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.jdbc.DataSourceBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;

    import javax.sql.DataSource;
    import java.util.HashMap;
    import java.util.Map;

    /**
    * 关于数据源配置,参考SpringBoot官方文档第79章《Data Access》
    * 79. Data Access
    * 79.1 Configure a Custom DataSource
    * 79.2 Configure Two DataSources
    */
    @Slf4j
    @Configuration
    public class DataSourceConfig {

    @Bean
    @ConfigurationProperties("spring.datasource.master")
    public DataSource masterDataSource() {
    return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.slave1")
    public DataSource slave1DataSource() {
    return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.slave2")
    public DataSource slave2DataSource() {
    return DataSourceBuilder.create().build();
    }

    @Bean
    public DataSource myRoutingDataSource(@Qualifier("masterDataSource") DataSource masterDataSource,
    @Qualifier("slave1DataSource") DataSource slave1DataSource,
    @Qualifier("slave2DataSource") DataSource slave2DataSource) {
    Map<Object, Object> targetDataSources = new HashMap<>();
    targetDataSources.put(DBTypeEnum.MASTER, masterDataSource);
    targetDataSources.put(DBTypeEnum.SLAVE1, slave1DataSource);
    targetDataSources.put(DBTypeEnum.SLAVE2, slave2DataSource);
    MyRoutingDataSource myRoutingDataSource = new MyRoutingDataSource();
    myRoutingDataSource.setDefaultTargetDataSource(masterDataSource);
    myRoutingDataSource.setTargetDataSources(targetDataSources);
    log.info("==============DataSourceConfig =====================");
    return myRoutingDataSource;
    }
    }



    ################### 数据配置 start ##########################
    datasource:
    master:
    jdbc-url: jdbc:mysql://47.103.114.48:3306/box_mall?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false&autoReconnect=true&failOverReadOnly=false
    username: boxlife
    password: boxlife2019
    driver-class-name: com.mysql.cj.jdbc.Driver
    druid:
    initial-size: 5
    max-active: 25
    min-idle: 5
    max-wait: 120000
    min-evictable-idle-time-millis: 30000
    max-evictable-idle-time-millis: 30000
    time-between-eviction-runs-millis: 0
    validation-query: select 1
    validation-query-timeout: -1
    test-on-borrow: false
    test-on-return: false
    test-while-idle: true
    pool-prepared-statements: true
    max-open-prepared-statements: 100
    filters: stat
    share-prepared-statements: true
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
    slave1:
    jdbc-url: jdbc:mysql://47.103.114.48:3306/box_mall?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false&autoReconnect=true&failOverReadOnly=false
    username: boxlife
    password: boxlife2019
    driver-class-name: com.mysql.cj.jdbc.Driver
    druid:
    initial-size: 5
    max-active: 25
    min-idle: 5
    max-wait: 120000
    min-evictable-idle-time-millis: 30000
    max-evictable-idle-time-millis: 30000
    time-between-eviction-runs-millis: 0
    validation-query: select 1
    validation-query-timeout: -1
    test-on-borrow: false
    test-on-return: false
    test-while-idle: true
    pool-prepared-statements: true
    max-open-prepared-statements: 100
    filters: stat
    share-prepared-statements: true
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
    slave2:
    jdbc-url: jdbc:mysql://47.103.114.48:3306/box_mall?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false&autoReconnect=true&failOverReadOnly=false
    username: boxlife
    password: boxlife2019
    driver-class-name: com.mysql.cj.jdbc.Driver
    druid:
    initial-size: 5
    max-active: 25
    min-idle: 5
    max-wait: 120000
    min-evictable-idle-time-millis: 30000
    max-evictable-idle-time-millis: 30000
    time-between-eviction-runs-millis: 0
    validation-query: select 1
    validation-query-timeout: -1
    test-on-borrow: false
    test-on-return: false
    test-while-idle: true
    pool-prepared-statements: true
    max-open-prepared-statements: 100
    filters: stat
    share-prepared-statements: true
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
    ################### mybatis plus start ##########################
    mybatis-plus:
    mapper-locations: classpath:/mapper/*Mapper.xml
    #实体扫描,多个package用逗号或者分号分隔
    typeAliasesPackage: com.box.member.model.entity
    #typeEnumsPackage: com.baomidou.springboot.entity.enums
    global-config:
    #刷新mapper 调试神器
    db-config:
    #主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
    id-type: INPUT
    #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
    field-strategy: not_empty
    #驼峰下划线转换
    column-underline: true
    #数据库大写下划线转换
    #capital-mode: true
    #逻辑删除配置 注解已配置
    #logic-delete-value: 1
    #logic-not-delete-value: 0
    db-type: mysql
    refresh: true
    #自定义填充策略接口实现
    #meta-object-handler: com.baomidou.springboot.xxx
    #自定义SQL注入器
    #sql-injector: com.baomidou.mybatisplus.extension.injector.LogicSqlInjector
    configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false




    package com.box.batisplus.config;

    /**
    * 数据源配置
    *
    * @author yuan.dingwang
    * @date 2021年03月30日 15:36
    */

    import com.box.batisplus.db.source.MyRoutingDataSource;
    import com.box.batisplus.enums.DBTypeEnum;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.jdbc.DataSourceBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;

    import javax.sql.DataSource;
    import java.util.HashMap;
    import java.util.Map;

    /**
    * 关于数据源配置,参考SpringBoot官方文档第79章《Data Access》
    * 79. Data Access
    * 79.1 Configure a Custom DataSource
    * 79.2 Configure Two DataSources
    */
    @Slf4j
    @Configuration
    public class DataSourceConfig {

    @Bean
    @ConfigurationProperties("spring.datasource.master")
    public DataSource masterDataSource() {
    return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.slave1")
    public DataSource slave1DataSource() {
    return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.slave2")
    public DataSource slave2DataSource() {
    return DataSourceBuilder.create().build();
    }

    @Bean
    public DataSource myRoutingDataSource(@Qualifier("masterDataSource") DataSource masterDataSource,
    @Qualifier("slave1DataSource") DataSource slave1DataSource,
    @Qualifier("slave2DataSource") DataSource slave2DataSource) {
    Map<Object, Object> targetDataSources = new HashMap<>();
    targetDataSources.put(DBTypeEnum.MASTER, masterDataSource);
    targetDataSources.put(DBTypeEnum.SLAVE1, slave1DataSource);
    targetDataSources.put(DBTypeEnum.SLAVE2, slave2DataSource);
    MyRoutingDataSource myRoutingDataSource = new MyRoutingDataSource();
    myRoutingDataSource.setDefaultTargetDataSource(masterDataSource);
    myRoutingDataSource.setTargetDataSources(targetDataSources);
    log.info("==============DataSourceConfig =====================");
    return myRoutingDataSource;
    }
    }


     

    小蚊子大人
  • 相关阅读:
    PHP中的call_user_func()与call_user_func_array()简单理解
    PHP实现多继承
    PHP实现多继承 trait 语法
    PHP几种常见魔术方法与魔术变量解析
    tp5 的nginx配置
    PHP 扩展 trie-tree, swoole过滤敏感词方案
    PHP Ajax跨域问题解决办法
    附加个人作业
    学完软工的感受
    团队介绍
  • 原文地址:https://www.cnblogs.com/ywsheng/p/14944450.html
Copyright © 2020-2023  润新知