springboot2配置多数据源,整合mybatisplus增强插件

     2022-03-30     424

关键词:

本文源码:GitHub·点这里 || GitEE·点这里

一、项目案例简介

1、多数据简介

实际的项目中,经常会用到不同的数据库以满足项目的实际需求。随着业务的并发量的不断增加,一个项目使用多个数据库:主从复制、读写分离、分布式数据库等方式,越来越常见。

2、MybatisPlus简介

MyBatis-Plus(简称 MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。

插件特点

无代码侵入:只做增强不做改变,引入它不会对现有工程产生影响。
强大的 CRUD 操作:通过少量配置即可实现单表大部分 CRUD 操作满足各类使用需求。
支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件。
支持主键自动生成:可自由配置,解决主键问题。
内置代码生成器:采用代码或者 Maven 插件可快速生成各层代码。
内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作。
内置性能分析插件:可输出 Sql 语句以及其执行时间。

二、多数据源案例

1、项目结构

技术图片

注意:mapper层和mapper.xml层分别放在不同目录下,以便mybatis扫描加载。

2、多数据源配置

spring:
  # 数据源配置
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    admin-data:
      driverClassName: com.mysql.jdbc.Driver
      dbUrl: jdbc:mysql://127.0.0.1:3306/cloud-admin-data?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&useSSL=false
      username: root
      password: 123
      initialSize: 20
      maxActive: 100
      minIdle: 20
      maxWait: 60000
      poolPreparedStatements: true
      maxPoolPreparedStatementPerConnectionSize: 30
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 30000
      maxEvictableIdleTimeMillis: 60000
      validationQuery: SELECT 1 FROM DUAL
      testOnBorrow: false
      testOnReturn: false
      testWhileIdle: true
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      filters: stat,wall
    user-data:
      driverClassName: com.mysql.jdbc.Driver
      dbUrl: jdbc:mysql://127.0.0.1:3306/cloud-user-data?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&useSSL=false
      username: root
      password: 123
      initialSize: 20
      maxActive: 100
      minIdle: 20
      maxWait: 60000
      poolPreparedStatements: true
      maxPoolPreparedStatementPerConnectionSize: 30
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 30000
      maxEvictableIdleTimeMillis: 60000
      validationQuery: SELECT 1 FROM DUAL
      testOnBorrow: false
      testOnReturn: false
      testWhileIdle: true
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      filters: stat,wall

这里参数的形式是多样的,只需要配置参数扫描即可。

3、参数扫描类

@Component
@ConfigurationProperties(prefix = "spring.datasource.admin-data")
public class DruidOneParam {
    private String dbUrl;
    private String username;
    private String password;
    private String driverClassName;
    private int initialSize;
    private int maxActive;
    private int minIdle;
    private int maxWait;
    private boolean poolPreparedStatements;
    private int maxPoolPreparedStatementPerConnectionSize;
    private int timeBetweenEvictionRunsMillis;
    private int minEvictableIdleTimeMillis;
    private int maxEvictableIdleTimeMillis;
    private String validationQuery;
    private boolean testWhileIdle;
    private boolean testOnBorrow;
    private boolean testOnReturn;
    private String filters;
    private String connectionProperties;
    // 省略 GET 和 SET
}

4、配置Druid连接池

@Configuration
@MapperScan(basePackages = {"com.data.source.mapper.one"},sqlSessionTemplateRef = "sqlSessionTemplateOne")
public class DruidOneConfig {
    private static final Logger LOGGER = LoggerFactory.getLogger(DruidOneConfig.class) ;
    @Resource
    private DruidOneParam druidOneParam ;
    @Bean("dataSourceOne")
    public DataSource dataSourceOne () {
        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(druidOneParam.getDbUrl());
        datasource.setUsername(druidOneParam.getUsername());
        datasource.setPassword(druidOneParam.getPassword());
        datasource.setDriverClassName(druidOneParam.getDriverClassName());
        datasource.setInitialSize(druidOneParam.getInitialSize());
        datasource.setMinIdle(druidOneParam.getMinIdle());
        datasource.setMaxActive(druidOneParam.getMaxActive());
        datasource.setMaxWait(druidOneParam.getMaxWait());
        datasource.setTimeBetweenEvictionRunsMillis(druidOneParam.getTimeBetweenEvictionRunsMillis());
        datasource.setMinEvictableIdleTimeMillis(druidOneParam.getMinEvictableIdleTimeMillis());
        datasource.setMaxEvictableIdleTimeMillis(druidOneParam.getMaxEvictableIdleTimeMillis());
        datasource.setValidationQuery(druidOneParam.getValidationQuery());
        datasource.setTestWhileIdle(druidOneParam.isTestWhileIdle());
        datasource.setTestOnBorrow(druidOneParam.isTestOnBorrow());
        datasource.setTestOnReturn(druidOneParam.isTestOnReturn());
        datasource.setPoolPreparedStatements(druidOneParam.isPoolPreparedStatements());
        datasource.setMaxPoolPreparedStatementPerConnectionSize(druidOneParam.getMaxPoolPreparedStatementPerConnectionSize());
        try {
            datasource.setFilters(druidOneParam.getFilters());
        } catch (Exception e) {
            LOGGER.error("druid configuration initialization filter", e);
        }
        datasource.setConnectionProperties(druidOneParam.getConnectionProperties());
        return datasource;
    }
    @Bean
    public SqlSessionFactory sqlSessionFactoryOne() throws Exception{
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        factory.setDataSource(dataSourceOne());
        factory.setMapperLocations(resolver.getResources("classpath*:/dataOneMapper/*.xml"));
        return factory.getObject();
    }
    @Bean(name="transactionManagerOne")
    public DataSourceTransactionManager transactionManagerOne(){
        return  new DataSourceTransactionManager(dataSourceOne());
    }
    @Bean(name = "sqlSessionTemplateOne")
    public SqlSessionTemplate sqlSessionTemplateOne() throws Exception {
        return new SqlSessionTemplate(sqlSessionFactoryOne());
    }
}

注意事项

  • MapperScan 在指定数据源上配置;
  • SqlSessionFactory 配置扫描的Mapper.xml地址 ;
  • DataSourceTransactionManager 配置该数据源的事务;
  • 两个数据源的配置手法相同,不赘述 ;

5、操作案例

  • 数据源一:简单查询
    @Service
    public class AdminUserServiceImpl implements AdminUserService {
    @Resource
    private AdminUserMapper adminUserMapper ;
    @Override
    public AdminUser selectByPrimaryKey (Integer id) {
        return adminUserMapper.selectByPrimaryKey(id) ;
    }
    }
  • 数据源二:事务操作
    @Service
    public class UserBaseServiceImpl implements UserBaseService {
    @Resource
    private UserBaseMapper userBaseMapper ;
    @Override
    public UserBase selectByPrimaryKey(Integer id) {
        return userBaseMapper.selectByPrimaryKey(id);
    }
    // 使用指定数据源的事务
    @Transactional(value = "transactionManagerTwo")
    @Override
    public void insert(UserBase record) {
        // 这里数据写入失败
        userBaseMapper.insert(record) ;
        // int i = 1/0 ;
    }
    }

    注意:这里的需要指定该数据源配置的事务管理器。

三、MybatisPlus案例

1、核心依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.0.7.1</version>
    <exclusions>
        <exclusion>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>3.0.7.1</version>
</dependency>

2、配置文件

mybatis-plus:
  mapper-locations: classpath*:/mapper/*.xml
  typeAliasesPackage: com.digital.market.*.entity
  global-config:
    db-config:
      id-type: AUTO
      field-strategy: NOT_NULL
      logic-delete-value: -1
      logic-not-delete-value: 0
    banner: false
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
    cache-enabled: false
    call-setters-on-nulls: true
    jdbc-type-for-null: ‘null‘

3、分层配置

mapper层
UserBaseMapper extends BaseMapper<UserBase>
实现层
UserBaseServiceImpl extends ServiceImpl<UserBaseMapper,UserBase> implements UserBaseService
接口层
UserBaseService extends IService<UserBase>

4、mapper.xml文件

<mapper namespace="com.plus.batis.mapper.UserBaseMapper" >
  <resultMap id="BaseResultMap" type="com.plus.batis.entity.UserBase" >
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="user_name" property="userName" jdbcType="VARCHAR" />
    <result column="pass_word" property="passWord" jdbcType="VARCHAR" />
    <result column="phone" property="phone" jdbcType="VARCHAR" />
    <result column="email" property="email" jdbcType="VARCHAR" />
    <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
    <result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
    <result column="state" property="state" jdbcType="INTEGER" />
  </resultMap>
  <sql id="Base_Column_List" >
    id, user_name, pass_word, phone, email, create_time, update_time, state
  </sql>
  <select id="selectByParam" parameterType="com.plus.batis.entity.QueryParam" resultMap="BaseResultMap">
    select * from hc_user_base
  </select>
</mapper>

注意事项

BaseMapper中的方法都已默认实现;这里也可以自定义实现一些自己的方法。

5、演示接口

@RestController
@RequestMapping("/user")
public class UserBaseController {
    private static final Logger LOGGER = LoggerFactory.getLogger(UserBaseController.class) ;
    @Resource
    private UserBaseService userBaseService ;
    @RequestMapping("/info")
    public UserBase getUserBase (){
        return userBaseService.getById(1) ;
    }
    @RequestMapping("/queryInfo")
    public String queryInfo (){
        UserBase userBase1 = userBaseService.getOne(new QueryWrapper<UserBase>().orderByDesc("create_time")) ;
        LOGGER.info("倒叙取值:{}",userBase1.getUserName());
        Integer count = userBaseService.count() ;
        LOGGER.info("查询总数:{}",count);
        UserBase userBase2 = new UserBase() ;
        userBase2.setId(1);
        userBase2.setUserName("spring");
        boolean resFlag = userBaseService.saveOrUpdate(userBase2) ;
        LOGGER.info("保存更新:{}",resFlag);
        Map<String, Object> listByMap = new HashMap<>() ;
        listByMap.put("state","0") ;
        Collection<UserBase> listMap = userBaseService.listByMap(listByMap) ;
        LOGGER.info("ListByMap查询:{}",listMap);
        boolean removeFlag = userBaseService.removeById(3) ;
        LOGGER.info("删除数据:{}",removeFlag);
        return "success" ;
    }
    @RequestMapping("/queryPage")
    public IPage<UserBase> queryPage (){
        QueryParam param = new QueryParam() ;
        param.setPage(1);
        param.setPageSize(10);
        param.setUserName("cicada");
        param.setState(0);
        return userBaseService.queryPage(param) ;
    }
    @RequestMapping("/pageHelper")
    public PageInfo<UserBase> pageHelper (){
        return userBaseService.pageHelper(new QueryParam()) ;
    }
}

这里pageHelper方法是使用PageHelper插件自定义的方法。

四、源代码地址

GitHub·地址
https://github.com/cicadasmile/middle-ware-parent
GitEE·地址
https://gitee.com/cicadasmile/middle-ware-parent

技术图片

springboot2整合jta组件,多数据源事务管理

本文源码:GitHub·点这里||GitEE·点这里一、JTA组件简介1、JTA基本概念JTA即Java-Transaction-API,JTA允许应用程序执行分布式事务处理,即在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序对JTA的支持极大地增强了数据访... 查看详情

springboot学习入门简易版八---springboot2.0多环境配置整合mybatismysql8+(19-20)(代码片段)

2.11SpringBoot多环境配置(19) application.properties中配置Spring.profiles.active=prd配置环境:Application-dev.properties开发环境Application-test.properties测试环境Application-uat.properties用户测试环境Application-prd.proper 查看详情

springboot2.xredis多数据源配置(jedis,lettuce)

SpringBoot2.xRedis多数据源配置(jedis,lettuce)96不敢预言的预言家0.12018.11.1314:22*字数65阅读727评论0喜欢2多数据源最终表现其实就是redisconnectionfactory不同springboot默认的redis配置维护了一套connectionfactory自己维护一套connectionfactory即可实现... 查看详情

springboot2+druid+mybatis多数据源配置(代码片段)

...案。读写分离会使用多数据源的使用。下面记录如何搭建SpringBoot2+Druid+Mybatis 多数据源配置以及在使用过程遇到的问题。一、先从pom.xml入手(使用springboot2的版本)<parent><groupId>org.springframework.boot&l 查看详情

springboot2.x:mybatis多数据源配置

前言MyBatis多数据源配置,最近在项目建设中,需要在原有系统上扩展一个新的业务模块,特意将数据库分库,以便减少复杂度。本文直接以简单的代码示例,如何对MyBatis多数据源配置。准备创建数据库db_testSETNAMESutf8mb4;SETFOREIGN_... 查看详情

springboot2.x下多数据源配置

本文同样适用于2.x版本下Mybatis的多数据源配置项目中经常会遇到一个项目需要访问多个数据源的情况,多数情况下可以参考这个教程进行配置。不过该教程适合springboot1.x版本,由于2.x版本修改默认连接池为Hikari,所以该教程中... 查看详情

springboot2.0之八多数据源配置

 在开发的过程中我们可能都会遇到对接公司其他系统等需求,对于外部的系统可以采用接口对接的方式,对于一个公司开发的两个系统,并且知道相关数据库结构的情况下,就可以考虑使用多数据源来解决这个问题。SpringBoo... 查看详情

springboot2.x基础教程:springboot整合mybatis附源码(代码片段)

微信号:hzy1014211086,如果你正在学习SpringBoot,可以加入我们的Spring技术交流群,共同成长文章目录一、准备数据表二、添加依赖三、配置数据源四、编写领域对象五、注解配置方式新增修改查询删除六、XML配置... 查看详情

springboot2.x系列教程48--多数据源配置之aop动态切换数据源

SpringBoot2.x系列教程48--多数据源配置之AOP动态切换数据源作者:一一哥在上一节中,我通过分包的方式实现了多数据源的配置,接下来我通过AOP切面的方式,带领大家实现第二种多数据源配置方式,该方式是在前面案例的基础上... 查看详情

springboot2.x系列教程48--多数据源配置之aop动态切换数据源

SpringBoot2.x系列教程48--多数据源配置之AOP动态切换数据源作者:一一哥在上一节中,我通过分包的方式实现了多数据源的配置,接下来我通过AOP切面的方式,带领大家实现第二种多数据源配置方式,该方式是在前面案例的基础上... 查看详情

springboot2整合knife4j

knife4j官网: https://doc.xiaominfo.com/guide/useful.html#java%E5%BC%80%E5%8F%91这玩艺就swagger的升级版,但是用起来比swagger方便多了,至少不会出现莫名的版本兼容问题下面记录一个配置示例 1. 代码结构 2.pom.xml<?xmlversion="1.0"enc... 查看详情

springboot2整合sharding-jdbc启动报错,坑多多

 原文地址:https://www.520mwx.com/view/931431、查看项目是否引入自动配置的数据源(比如druid-spring-boot-starter),如果有,先删除,sharding启动时会自动创建数据源,两者冲突。如果还是想用druid链接池。引入: <dependency><... 查看详情

springboot2.0之整合elasticsearch

就类比数据库到时候去实现服务器端配置集群名字 与yml名字一致pom:<projectxmlns="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.0ht 查看详情

Spring Boot 2 多数据源配置

】SpringBoot2多数据源配置【英文标题】:SpringBoot2multipledatasourceconfguration【发布时间】:2019-09-0917:34:10【问题描述】:我正在尝试为springboot2应用程序配置多个数据源,从只读SQLitedb文件读取并将结果写入不同的SQLitedb。我找不到... 查看详情

springboot应用系列5--springboot2整合logback

上一篇我们梳理了SpringBoot2整合log4j2的配置过程,其中讲到了SpringBoot2原装适配logback,并且在非异步环境下logback和log4j2的性能差别不大,所以对于那些日志量不算太高的项目来说,选择logback更简单方便。1.pom.xmlpom.xml不需要添加... 查看详情

springboot2+springsecurity+cas整合认证(代码片段)

...最后一步,实践检验真理的最后一步9.结束语1.前言下面SpringBoot2+SpringSecurity+CAS安全认证整合项目2.pom.xml<?xmlversion="1.0"e 查看详情

springboot2——数据访问的集成&单元测试(junit5)(代码片段)

SpringBoot2——数据访问的集成&单元测试(JUnit5)一、数据访问1.1数据库场景的自动配置(HikariDataSource)1.2整合druid数据源1.2.1自定义druid数据源1.2.2使用官方starter方式1.3整合MyBatis操作(重点)1.3.1整合过... 查看详情

springboot2系列教程|整合数据缓存cache

如题,今天介绍SpringBoot的数据缓存。做过开发的都知道程序的瓶颈在于数据库,我们也知道内存的速度是大大快于硬盘的,当需要重复获取相同数据时,一次又一次的请求数据库或者远程服务,导致大量时间耗费在数据库查询... 查看详情