在Mybatis plus中如何实现配置多数据源

发布时间:2020-11-06 17:35:57 作者:Leah
来源:亿速云 阅读:690

这期内容当中小编将会给大家带来有关在Mybatis plus中如何实现配置多数据源,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

一. mybatis plus

因为我们项目是springboot+mybatis plus,有些人一看,mybatis还知道对吧,mybatis plus是什么鬼,其实字面意思可以理解,就是对mybatis进行一些功能改造,一些封装升级,然后用起来特别方便。

核心功能的升级主要是以下三点:

支持通用的 CRUD、代码生成器与条件构造器。

通用 CRUD:定义好 Mapper 接口后,只需要继承 BaseMapper<T> 接口即可获得通用的增删改查功能,无需编写任何接口方法与配置文件
条件构造器:通过 EntityWrapper<T> (实体包装类),可以用于拼接 SQL 语句,并且支持排序、分组查询等复杂的 SQL
代码生成器:支持一系列的策略配置与全局配置,比 MyBatis 的代码生成更好用

二.多数据源配置开始

思路:

1、yml中配置多个数据源信息
2、通过AOP切换不同数据源
3、配合mybatis plus使用

1、yml配置

spring:
 aop:
   proxy-target-class: true
   auto: true
 datasource:
  druid:
   db1:
    url: jdbc:mysql://localhost:3306/eboot
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
    initialSize: 5
    minIdle: 5
    maxActive: 20
   db2:
    url: jdbc:oracle:thin:@192.168.136.222:ORCL
    username: sa
    password: sa123456
    driver-class-name: oracle.jdbc.OracleDriver
    initialSize: 5
    minIdle: 5
    maxActive: 20

2、启动多个数据源

@EnableTransactionManagement //开启事务
@Configuration //spring中常用到注解,与xml配置相对立。是两种加载bean方式
@MapperScan("com.df.openapi.**.mapper.db*") // 扫描mapperdao的地址
public class MybatisPlusConfig {
 
  @Bean
  public PaginationInterceptor paginationInterceptor() {
    PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
//    paginationInterceptor.setLocalPage(true); // 由于版本问题,有些类可能招不到这个方法,需要升级jar包
    return paginationInterceptor;
  }
 
  @Bean(name = "db1")
  @ConfigurationProperties(prefix = "spring.datasource.druid.db1")
  public DataSource db1() {
    return DruidDataSourceBuilder.create().build();
  }
 
  @Bean(name = "db2")
  @ConfigurationProperties(prefix = "spring.datasource.druid.db2")
  public DataSource db2() {
    return DruidDataSourceBuilder.create().build();
  }
 
  /**
   * 动态数据源配置
   *
   * @return
   */
  @Bean
  @Primary
  public DataSource multipleDataSource(@Qualifier("db1") DataSource db1,
                     @Qualifier("db2") DataSource db2) {
    DynamicDataSource dynamicDataSource = new DynamicDataSource();
    Map<Object, Object> targetDataSources = new HashMap<>();
    targetDataSources.put(DBTypeEnum.db1.getValue(), db1);
    targetDataSources.put(DBTypeEnum.db2.getValue(), db2);
    dynamicDataSource.setTargetDataSources(targetDataSources);
    dynamicDataSource.setDefaultTargetDataSource(db2); // 程序默认数据源,这个要根据程序调用数据源频次,经常把常调用的数据源作为默认
    return dynamicDataSource;
  }
 
  @Bean("sqlSessionFactory")
  public SqlSessionFactory sqlSessionFactory() throws Exception {
    MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
    sqlSessionFactory.setDataSource(multipleDataSource(db1(), db2()));
 
    MybatisConfiguration configuration = new MybatisConfiguration();
    configuration.setJdbcTypeForNull(JdbcType.NULL);
    configuration.setMapUnderscoreToCamelCase(true);
    configuration.setCacheEnabled(false);
    sqlSessionFactory.setConfiguration(configuration);
    //PerformanceInterceptor(),OptimisticLockerInterceptor()
    //添加分页功能
    sqlSessionFactory.setPlugins(new Interceptor[]{
        paginationInterceptor()
    });
//    sqlSessionFactory.setGlobalConfig(globalConfiguration()); //注释掉全局配置,因为在xml中读取就是全局配置
    return sqlSessionFactory.getObject();
  }
 
 /*  @Bean
  public GlobalConfiguration globalConfiguration() {
    GlobalConfiguration conf = new GlobalConfiguration(new LogicSqlInjector());
    conf.setLogicDeleteValue("-1");
    conf.setLogicNotDeleteValue("1");
    conf.setIdType(0);
    conf.setMetaObjectHandler(new MyMetaObjectHandler());
    conf.setDbColumnUnderline(true);
    conf.setRefresh(true);
    return conf;
  }*/
}

3、DBType枚举类

package com.df.openapi.config.db;
 
public enum DBTypeEnum {
 
  db1("db1"), db2("db2");
  private String value;
 
  DBTypeEnum(String value) {
    this.value = value;
  }
 
  public String getValue() {
    return value;
  }
}

4、动态数据源决策

package com.df.openapi.config.db;
 
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
 
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final Logger LOGGER = LoggerFactory.getLogger(DynamicDataSource.class);
@Override
protected Object determineCurrentLookupKey() {
  String datasource = DataSourceContextHolder.getDbType();
  LOGGER.debug("使用数据源 {}", datasource);
  return datasource;
}
}

5、设置、获取数据源

public class DataSourceContextHolder {
 
  private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceContextHolder.class);
 
  private static final ThreadLocal contextHolder = new ThreadLocal<>(); //实际上就是开启多个线程,每个线程进行初始化一个数据源
  /**
   * 设置数据源
   * @param dbTypeEnum
   */
  public static void setDbType(DBTypeEnum dbTypeEnum) {
    contextHolder.set(dbTypeEnum.getValue());
  }
 
  /**
   * 取得当前数据源
   * @return
   */
  public static String getDbType() {
    return (String) contextHolder.get();
  }
 
  /**
   * 清除上下文数据
   */
  public static void clearDbType() {
    contextHolder.remove();
  }
}

6、AOP实现的数据源切换

@Order设置的足够小是为了让他先执行

/**
 * aop的实现的数据源切换<br> * aop切点,实现mapper类找寻,找到所属大本营以后,如db1Aspect(),则会调用<br> * db1()前面之前的操作,进行数据源的切换。
 */
@Component
@Order(value = -100)
@Slf4j
@Aspect
public class DataSourceAspect {
 
  @Pointcut("execution(* com.zwyl.bazhong.dao.mapper.db1..*.*(..))")
  private void db1Aspect() {
  }
 
  @Pointcut("execution(* com.zwyl.bazhong.dao.mapper.db2..*.*(..))")
  private void db2Aspect() {
  }
 
  @Before("db1Aspect()")
  public void db1() {
    log.info("切换到db1 数据源...");
    DataSourceContextHolder.setDbType(DBTypeEnum.db1);
  }
 
  @Before("db2Aspect()")
  public void db2() {
    log.info("切换到db2 数据源...");
    DataSourceContextHolder.setDbType(DBTypeEnum.db2);
  }
}

7、mapper层结构

在Mybatis plus中如何实现配置多数据源

8、写一个service测试一下

@Service
public class DictServiceImpl implements IDictService {
 
  @Resource
  private PtDictMapper ptDictMapper; //来自db1
 
  @Resource
  private SysDictMapper sysDictMapper; // 来自db2
 
 
  @Override
  public void getById(String id) {
    PtDict dict = ptDictMapper.selectById("2bf6257fc8fe483c84c1ad7e89d632f6");
    SysDict sysDict = sysDictMapper.getById("49");
    System.out.println("123");
  }
}

9、测试结果

总结: 其实整个过程可以理解成,配置多数据源 xml中  -------> 然后通过加载多数源到spring工厂中-------->然后创建多线程,每个数据源对应一个数据源--------->然后实际调用时候,会先通过aop匹配到某一具体数据源------------->然后实例化当前数据源

上述就是小编为大家分享的在Mybatis plus中如何实现配置多数据源了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。

推荐阅读:
  1. springboot+mybatis-plus如何打印sql语句
  2. 多数据源如何利用MyBatis-Plus实现

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

mybatis plus 如何实现 多数据源

上一篇:使用Springboot如何实现多线程并注入bean

下一篇:在Zabbix中使用过滤器实现监控功能的方法

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》