zoukankan      html  css  js  c++  java
  • SpringBoot整合MyBatisPlus配置动态数据源

    SpringBoot整合MyBatisPlus配置动态数据源

    推文:2018开源中国最受欢迎的中国软件MyBatis-Plus

    MybatisPlus特性
    • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
    • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
    • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
    • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
    • 支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer2005、SQLServer 等多种数据库
    • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
    • 支持 XML 热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
    • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
    • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
    • 支持关键词自动转义:支持数据库关键词(order、key......)自动转义,还可自定义关键词
    • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
    • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
    • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
    • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
    • 内置 Sql 注入剥离器:支持 Sql 注入剥离,有效预防 Sql 注入攻击
    快速开始

    初始化测试数据表:

    DROP TABLE IF EXISTS user;
    
    CREATE TABLE user
    (
    	id BIGINT(20) NOT NULL COMMENT '主键ID',
    	name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    	age INT(11) NULL DEFAULT NULL COMMENT '年龄',
    	email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    	PRIMARY KEY (id)
    );
    DELETE FROM user;
    
    INSERT INTO user (id, name, age, email) VALUES
    (1, 'Jone', 18, 'test1@baomidou.com'),
    (2, 'Jack', 20, 'test2@baomidou.com'),
    (3, 'Tom', 28, 'test3@baomidou.com'),
    (4, 'Sandy', 21, 'test4@baomidou.com'),
    (5, 'Billie', 24, 'test5@baomidou.com');
    

    父工程依赖

    该工程用于依赖管理,pom如下:

    <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
            <mybatis-plus-version>3.1.1</mybatis-plus-version>
            <mysql-driver-version>5.1.47</mysql-driver-version>
            <druid-version>1.1.10</druid-version>
     </properties>
    
    <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-dependencies</artifactId>
                    <version>2.1.5.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    

    创建MyBaitsPlus工程

    依赖如下:

     <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <!-- mybatis plus -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus-version}</version>
            </dependency>
    
            <!-- mysql -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql-driver-version}</version>
            </dependency>
    
            <!-- druid数据连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid-version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
    
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
     </dependencies>
    
    properties配置

    在这里配置数据库连接,以及数据连接池与mybatisplus的配置等

    server.port=8080
    
    spring.application.name=mybatis
    
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&characterEncoding=utf8
    spring.datasource.username=root
    spring.datasource.password=root
    
    spring.datasource.druid.initial-size=5
    spring.datasource.druid.min-idle=5
    spring.datasource.druid.maxActive=20
    spring.datasource.druid.maxWait=60000
    spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
    spring.datasource.druid.minEvictableIdleTimeMillis=300000
    spring.datasource.druid.validationQuery=SELECT 1 FROM DUAL
    spring.datasource.druid.testWhileIdle=true
    spring.datasource.druid.testOnBorrow=false
    spring.datasource.druid.testOnReturn=false
    spring.datasource.druid.poolPreparedStatements=true
    spring.datasource.druid.maxPoolPreparedStatementPerConnectionSize=20
    spring.datasource.druid.filters=stat,slf4j
    spring.datasource.druid.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    spring.datasource.druid.web-stat-filter.enabled=true
    spring.datasource.druid.web-stat-filter.url-pattern=/*
    spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
    spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
    spring.datasource.druid.stat-view-servlet.allow=127.0.0.1,192.168.163.1
    spring.datasource.druid.stat-view-servlet.deny=192.168.1.73
    spring.datasource.druid.stat-view-servlet.reset-enable=false
    #Druid 管理账号
    spring.datasource.druid.stat-view-servlet.login-username=admin
    #Druid 管理密码
    spring.datasource.druid.stat-view-servlet.login-password=123456
    #com.simple.spring.boot.mapper 该包打印DEBUG级别日志
    logging.level.com.simple.spring.boot.mapper=debug
    
    #mybatis plus mapper文件路径
    mybatis-plus.mapperLocations=classpath:/mybatis/mapper/*.xml
    #mybaits plus 实体类路径
    mybatis-plus.typeAliasesPackage=com.simple.spring.**.entities
    mybatis-plus.typeEnumsPackage=
    #数据库相关配置
    #主键类型  AUTO:"数据库ID自增", INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
    mybatis-plus.global-config.db-config.id-type=UUID
    #字段策略 IGNORED:"忽略判断",NOT_NULL:"非 NULL 判断"),NOT_EMPTY:"非空判断"
    mybatis-plus.global-config.db-config.field-strategy=not_empty
    #驼峰下划线转换
    mybatis-plus.global-config.db-config.column-underline=true
    #数据库大写下划线转换
    #capital-mode: true
    #逻辑删除配置
    mybatis-plus.global-config.db-config.logic-delete-value=0
    mybatis-plus.global-config.db-config.logic-not-delete-value= 1
    #mybatis-plus.global-config.db-config.db-type= sqlserver
    #刷新mapper 调试神器
    mybatis-plus.global-config.refresh=true
    # 原生配置
    mybatis-plus.configuration.map-underscore-to-camel-case=true
    mybatis-plus.configuration.cache-enabled=false
    mybatis-plus.configuration.call-setters-on-nulls =true
    
    常规增删改查实现

    创建实体类:

    **
     * 实体类
     * @author: SimpleWu
     * @date: 2019/5/25
     */
    @Data
    public class User {
        private Long id;
        private String name;
        private Integer age;
        private String email;
    }
    

    lombok插件省去getset方法。

    创建UserMapper接口,并且实现BaseMapper<User>这里我们指定实体类为user可直接使用接口中的方法。

    • 查询所有数据

      public List<User> getList(){
              return userMapper.selectList(null);
      }
      
    • 查询数据带查询条件

      public List<User> getListQuery(){
              User user = new User();
              user.setName("SimpleWu");
              Wrapper<User> wrapper = new QueryWrapper<>(user);
              return userMapper.selectList(wrapper);
      }
      
    • 查询带分页

      public IPage<User> page(){
              int currentPage = 1 ; //当前页
              int pageSize = 2 ;//每页大小
              IPage<User> page = new Page(currentPage,pageSize);
              page = userMapper.selectPage(page,null);
              return page;
       }
      
    • 根据实体类新增数据

      @Transactional//本地事务开启
      public int insert(){
              User user = new User();
              user.setId(6l);
              user.setName("SimpleWu");
              user.setAge(100);
              user.setEmail("SimpleWu@gmail.com");
              return userMapper.insert(user);
       }
      
    • 根据主键删除数据

      @Transactional//本地事务开启
       public int deleteById(){
              int userId = 6;
              return userMapper.deleteById(userId);
      }
      
    • 根据ID更新数据

      @Transactional//本地事务开启
       public int updateById(){
              User user = new User();
              user.setId(5l);
              user.setName("update");
              user.setAge(100);
              user.setEmail("update@email.com");
             return userMapper.updateById(user);
      }
      
    • 条件构造器

      • UpdateWrapper 用于增删改构造条件
      • QueryWrapper 用于查询构造条件
      Transactional//本地事务开启
          public int updateWrapperUser(){
              User user = new User();
              user.setId(5l);
              user.setName("update");
              user.setAge(100);
              user.setEmail("update@email.com");
      
              User updateWrapperUser = new User();
              updateWrapperUser.setId(1l);
      
              /**
               * 修改 UpdateWrapper
               * 查询 QueryWrapper
               */
              Wrapper<User> wrapper = new UpdateWrapper<>(updateWrapperUser);
              return userMapper.update(user,wrapper);
       }
      
    • Mapper接口绑定Mapper文件

      • properites中配置既可

        #扫描mybatis/mapper下面的所有xml
        mybatis-plus.mapperLocations=classpath:/mybatis/mapper/*.xml
        
    • UserMapper接口测试

    public interface UserMapper extends BaseMapper<User> {
    
        Map<String,Object> queryUser(@Param("USER_ID") String userId);
    }
    

    UserMapper.xml,如下:

    <select id="queryUser" resultType="java.util.HashMap" parameterType="java.lang.String">
            SELECT
              ID,
              NAME
            FROM
              USER
            WHERE ID = #{USER_ID}
    </select>
    

    执行SQL:

    public Map<String,Object> myMapper(){
            return userMapper.queryUser("2");
    }
    

    在SpringBoot中使用MybatisPlus分页需要注入Bean,并且在启动类上使用@MapperScan("com.simple.spring.boot.mapper")扫描mapper文件路径如下:

    @SpringBootApplication
    @MapperScan("com.simple.spring.boot.mapper")
    public class MybatisPlusApplication {
    
        /**
         * 分页插件注册
         * @return
         */
        @Bean
        public PaginationInterceptor paginationInterceptor() {
            return new PaginationInterceptor();
        }
    
        public static void main(String[] args) {
            SpringApplication.run(MybatisPlusApplication.class, args);
        }
    
    }
    

    使用MyBatisPlus可以为我们减少很多很多的代码,不过需要编写实体类,有失必有得。

    配置动态数据源

    dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器。

    优势

    网上关于动态数据源的切换的文档有很多,核心只有两种。

    1. 构建多套环境,优势是方便控制也容易集成一些简单的分布式事务,缺点是非动态同时代码量较多,配置难度大。
    2. 基于spring提供原生的 AbstractRoutingDataSource ,参考一些文档自己实现切换。

    如果你的数据源较少,场景不复杂,选择以上任意一种都可以。如果你需要更多特性,请尝试本动态数据源。

    1. 数据源分组,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。
    2. 简单集成Druid数据源监控多数据源,简单集成Mybatis-Plus简化单表,简单集成P6sy格式化sql,简单集成Jndi数据源。
    3. 简化Druid和HikariCp配置,提供全局参数配置。
    4. 提供自定义数据源来源(默认使用yml或properties配置)。
    5. 项目启动后能动态增减数据源。
    6. 使用spel动态参数解析数据源,如从session,header和参数中获取数据源。(多租户架构神器)
    7. 多层数据源嵌套切换。(一个业务ServiceA调用ServiceB,ServiceB调用ServiceC,每个Service都是不同的数据源)
    8. 使用正则匹配或spel表达式来切换数据源(实验性功能)。

    劣势

    不能使用多数据源事务(同一个数据源下能使用事务),网上其他方案也都不能提供。

    如果你需要使用到分布式事务,那么你的架构应该到了微服务化的时候了。

    如果呼声强烈,项目达到800 star,作者考虑集成分布式事务。

    PS: 如果您只是几个数据库但是有强烈的需求分布式事务,建议还是使用传统方式自己构建多套环境集成atomic这类,网上百度很多。

    约定

    1. 本框架只做 切换数据源 这件核心的事情,并不限制你的具体操作,切换了数据源可以做任何CRUD。
    2. 配置文件所有以下划线 _ 分割的数据源 首部 即为组的名称,相同组名称的数据源会放在一个组下。
    3. 切换数据源即可是组名,也可是具体数据源名称,切换时默认采用负载均衡机制切换。
    4. 默认的数据源名称为 master ,你可以通过spring.datasource.dynamic.primary修改。
    5. 方法上的注解优先于类上注解。

    建议

    强烈建议在 主从模式 下遵循普遍的规则,以便他人能更轻易理解你的代码。

    主数据库 建议 只执行 INSERT UPDATE DELETE 操作。

    从数据库 建议 只执行 SELECT 操作。

    快速开始

    加入依赖:

    <!-- 动态数据源 -->
    <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
                <version>2.5.4</version>
    </dependency>
    

    注释掉原来的数据库配置,加入:

    #设置默认的数据源或者数据源组,默认值即为master
    spring.datasource.dynamic.primary=master
    #主库配置
    spring.datasource.dynamic.datasource.master.username=root
    spring.datasource.dynamic.datasource.master.password=root
    spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.dynamic.datasource.master.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&characterEncoding=utf8
    #从库配置
    spring.datasource.dynamic.datasource.slave_1.username=root
    spring.datasource.dynamic.datasource.slave_1.password=root
    spring.datasource.dynamic.datasource.slave_1.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.dynamic.datasource.slave_1.url=jdbc:mysql://localhost:3307/mybatis?useSSL=false&characterEncoding=utf8
    

    使用 @DS 切换数据源。

     @DS("master")
        public List<User> getListQuery(){
            User user = new User();
            user.setName("SimpleWu");
            Wrapper<User> wrapper = new QueryWrapper<>(user);
            return userMapper.selectList(wrapper);
        }
    
        @DS("slave_1")
        public IPage<User> page(){
            int currentPage = 1 ; //当前页
            int pageSize = 2 ;//每页大小
            IPage<User> page = new Page(currentPage,pageSize);
            page = userMapper.selectPage(page,null);
            return page;
        }
    

    @DS 可以注解在方法上和类上,同时存在方法注解优先于类上注解

    注解在service实现或mapper接口方法上,但强烈不建议同时在service和mapper注解。 (可能会有问题)

    如果不加入主键则使用默认数据源。

    DruidDataSourceAutoConfigure会注入一个DataSourceWrapper,其会在原生的spring.datasource下找url,username,password等。而我们动态数据源的配置路径是变化的,所以需要排除:

    spring:
      autoconfigure:
        exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
    

    或者在类上排除:

    @SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)
    

    然后更换properties配置信息:

    #公共配置 Druid登录账号 密码
    spring.datasource.druid.stat-view-servlet.login-username=admin
    spring.datasource.druid.stat-view-servlet.login-password=123456
    spring.datasource.dynamic.druid.initial-size=5
    spring.datasource.dynamic.druid.min-idle=5
    spring.datasource.dynamic.druid.maxActive=20
    spring.datasource.dynamic.druid.maxWait=60000
    spring.datasource.dynamic.druid.timeBetweenEvictionRunsMillis=60000
    spring.datasource.dynamic.druid.minEvictableIdleTimeMillis=300000
    spring.datasource.dynamic.druid.validationQuery=SELECT 1 FROM DUAL
    spring.datasource.dynamic.druid.testWhileIdle=true
    spring.datasource.dynamic.druid.testOnBorrow=false
    spring.datasource.dynamic.druid.testOnReturn=false
    spring.datasource.dynamic.druid.poolPreparedStatements=true
    spring.datasource.dynamic.druid.maxPoolPreparedStatementPerConnectionSize=20
    spring.datasource.dynamic.druid.filters=stat,slf4j
    spring.datasource.dynamic.druid.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    spring.datasource.dynamic.druid.web-stat-filter.enabled=true
    spring.datasource.dynamic.druid.web-stat-filter.url-pattern=/*
    spring.datasource.dynamic.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
    spring.datasource.dynamic.druid.stat-view-servlet.url-pattern=/druid/*
    spring.datasource.dynamic.druid.stat-view-servlet.allow=127.0.0.1,192.168.163.1
    spring.datasource.dynamic.druid.stat-view-servlet.deny=192.168.1.73
    spring.datasource.dynamic.druid.stat-view-servlet.reset-enable=false
    

    本篇代码案例地址:

    https://github.com/450255266/open-doubi

  • 相关阅读:
    sc 使用
    sql端点应用
    今天面试笔试了一道SQL面试题,狠简单
    指定域的名称或安全标识SID与该域的信任信息不一致
    查询登陆时间间隔不超过5分钟的所有记录
    sql打开xls
    Android控件开发
    android开发1【转】网络设备状态检测
    google.maps Simple Polylines
    Notification 使用详解(很全
  • 原文地址:https://www.cnblogs.com/SimpleWu/p/10930388.html
Copyright © 2011-2022 走看看