SpringBoot整合MyBatisPlus配置动态数据源的方法
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
本篇代码案例地址:
总结
以上所述是小编给大家介绍的springboot整合mybatisplus配置动态数据源的方法,希望对大家有所帮助