Mybatis-Plus简介
一、简介
MyBatis-Plus是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为了简化开发、提升效率而生。MyBatis-Plus提供了通用的mapper和service,可以在不编写任何SQL语句的情况下,快速的实现对单表的CRUD、批量、逻辑删除、分页等操作
二、MyBatis-Plus的特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
- 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
- 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
三、支持的数据库
MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb
达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库
四、架构解析

五、代码托管
官方地址: http://mp.baomidou.com
代码发布地址:
Github: https://github.com/baomidou/mybatis-plus
Gitee: https://gitee.com/baomidou/mybatis-plus
文档发布地址: https://baomidou.com/pages/24112f
六、环境搭建
下面是基于Maven、springboot、MySQL和mybatis-plus进行了环境的搭建,实现需求对于user表实现增删改查操作,SQL如下:
CREATE TABLE `user` ( `uid` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `username` varchar(30) DEFAULT NULL COMMENT '姓名', `age` int(11) DEFAULT NULL COMMENT '年龄', `email` varchar(50) DEFAULT NULL COMMENT '邮箱',PRIMARY KEY (`uid`) ) ENGINE=InnoDB AUTO_INCREMENT=1596042777899077635 DEFAULT CHARSET=utf8;
插入默认数据如下:
INSERT INTO user (id, name, age, email) VALUES
(1, '青翼蝠王', 38, 'weiyixiao@baomidou.com'),
(2, '紫衫龙王', 23, 'daiqisi@baomidou.com'),
(3, '白眉鹰王', 28, 'yintianzheng@baomidou.com'),
(4, '金毛狮王', 21, 'xiexun@baomidou.com')
1.创建springboot项目

输入模块名称、包名、选择Maven项目和Java版

选择spring web开发

2.在pom.xml中导入依赖
<!--lombok依赖--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> <scope>provided</scope> </dependency> <!--MySQL数据库连接的依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> <!--添加druid连接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!--mybatis-plus启动器--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.2</version> </dependency>
3.准备配置文件
在resource目录下面创建application.yml配置文件,内容如下:
spring: datasource: # 使用阿里的Druid连接池 type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver # 填写你数据库的url、登录名、密码和数据库名 url: jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai username: root password: 123456 druid: # 连接池的配置信息 # 初始化大小,最小,最大 initial-size: 5 min-idle: 5 maxActive: 20 # 配置获取连接等待超时的时间 maxWait: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 timeBetweenEvictionRunsMillis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 testWhileIdle: true testOnBorrow: false testOnReturn: false # 打开PSCache,并且指定每个连接上PSCache的大小 poolPreparedStatements: true maxPoolPreparedStatementPerConnectionSize: 20 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 filters: stat,wall,slf4j # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000 # 配置DruidStatFilter web-stat-filter: enabled: true url-pattern: "/*" exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*" # 配置DruidStatViewServlet stat-view-servlet: url-pattern: "/druid/*" # IP白名单(没有配置或者为空,则允许所有访问) allow: 127.0.0.1,192.168.8.109 # IP黑名单 (存在共同时,deny优先于allow) deny: 192.168.1.188 # 禁用HTML页面上的“Reset All”功能 reset-enable: false # 登录名 login-username: admin # 登录密码 login-password: 123456 servlet: multipart: #设置文件上传单个文件的大小 max-file-size: 10MB #设置多个文件上传总文件的大小 file-size-threshold: 100MB server: servlet: context-path: /springboot10 port: 8080 mybatis-plus: #指定实体类的位置 type-aliases-package: com.augus.pojo #指定mapper映射文件的位置,这里默认就是mapper包下加载,可以不指定 #mapper-locations:
4.启动类配置
在Spring Boot启动类中添加@MapperScan注解,扫描mapper包,如果在这里添加,就需要到mapper层每一个接口上添加@Mapper注解
package com.augus; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.augus.mapper") //配置mapper扫描 public class Springboot10Application { public static void main(String[] args) { SpringApplication.run(Springboot10Application.class, args); } }
5.创建实体类
在com.augus下创建pojo存在实体类,创建User实体类
package com.augus.pojo; import com.baomidou.mybatisplus.annotation.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; @AllArgsConstructor @NoArgsConstructor @Data public class User implements Serializable {private Long id;private String name; private Integer age; private String email; }
6.创建mapper层
在com.augus中创建mapper包,在下面创建UserMapper
BaseMapper是MyBatis-Plus提供的模板mapper,其中包含了基本的CRUD方法,泛型为操作的,所以只需要继承BaseMapper,指定其泛型为User即可
package com.augus.mapper; import com.augus.pojo.User; import com.baomidou.mybatisplus.core.mapper.BaseMapper; public interface UserMapper extends BaseMapper<User> { }
7、测试环境
创建测试类:MybatisPlusTest,内容如下,实现查询User表中所有数据的操作
package com.augus; import com.augus.mapper.UserMapper; import com.augus.pojo.User; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.*; @SpringBootTest public class MybatisPlusTest { @Autowired private UserMapper userMapper; @Test public void testSelectList(){ //selectList根据mapper内置的的条件构造器查询一个list集合,null表示没有条件的查询 List<User> users = userMapper.selectList(null); users.forEach(System.out::println); } }
查询结果如下:

8.添加日志
通过mybatis-plus日志的集成可以清晰的看到执行的SQL,在application.yml中配置日志输出,添加内容
mybatis-plus: #指定实体类的位置 type-aliases-package: com.augus.pojo #指定mapper映射文件的位置,这里默认就是mapper包下加载,可以不指定 #mapper-locations: # 下面配置的是日志 configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

再次执行查询所有的数据,执行如下:

三、通过mybatis-plus实现基本的CRUD
1、BaseMapper
MyBatis-Plus中的基本CRUD在内置的BaseMapper中都已得到了实现,测试mapper层方法,创建MybatisPlusTest测试方法,代码如下:
package com.augus; import com.augus.mapper.UserMapper; import com.augus.pojo.User; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.*; @SpringBootTest public class MybatisPlusTest { @Autowired private UserMapper userMapper; @Test public void testSelectList(){ //selectList根据mapper内置的的条件构造器查询一个list集合,null表示没有条件的查询 List<User> users = userMapper.selectList(null); users.forEach(System.out::println); } @Test public void testSelectById(){ //通过id查询员工信息 User user = userMapper.selectById(4); System.out.println(user); } @Test public void testSelectListQueryWrapper(){ //通过QueryWrapper对象设置字段信息查询 QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(); //设置根据某个字段的值查询 userQueryWrapper.eq("name", "金毛狮王"); List<User> users = userMapper.selectList(userQueryWrapper); System.out.println(users); } //插入数据:这里只能每次插入一条数据,插入多条信息需要在service层完成,因为这里会出现一个SQL过长的问题 @Test public void testInsert(){ User user = new User(null,"说不得", 37,"shuobude@163.com"); int insert = userMapper.insert(user); System.out.println("受影响的行数:"+insert); //获取新增后自增的id System.out.println("id自动获取值为:"+ user.getId()); } @Test public void testDeleteById(){ //通过id删除记录 int i = userMapper.deleteById("1596069490267811843"); System.out.println("受影响的行数:"+i); } @Test public void testDeleteBatchIds(){ //通过多个id同时删除多个记录 ArrayList<Long> ids = new ArrayList<>(); //这里id是通过雪花算法生成的,所以长度很长,我这里是Long,加个L就表示是Long类型,不会出现错误了 ids.add(1596068821574193154L); ids.add(1596069408168476673L); ids.add(1596069490267811842L); int i = userMapper.deleteBatchIds(ids); System.out.println("受影响的行数:"+i); } @Test public void testDeleteByMap(){ //通过map集合设置条件删除 HashMap<String, Object> map = new HashMap<>(); map.put("name", "韩千叶"); map.put("age", "21"); int i = userMapper.deleteByMap(map); System.out.println("受影响的行数:"+i); } @Test public void testUpdateById(){ //根据id修改 信息 // 直接表示会出现整数过大的错误,在整数后面添加字母L,告诉Java这个整数是long型,系统就不报错了。 User user = new User(1596069490267811845L, "光明左使", 25, "yangxiao@163.com"); int i = userMapper.updateById(user); System.out.println("受影响的行数:"+i); } }
2.调用service层方法实现CURD操作
通用 Service CRUD 封装IService接口,进一步封装 CRUD 采用 get 查询单行 remove 删 除 list 查询集合 page 分页 前缀命名方式区分 Mapper 层避免混淆,泛型 T 为任意实体对象建议如果存在自定义通用 Service 方法的可能,请创建自己的 IBaseService 继承Mybatis-Plus 提供的基类
在com.augus下创建 UserService接口如下:
package com.augus.service; import com.augus.pojo.User; import com.baomidou.mybatisplus.extension.service.IService; //这里接口需要基础IService,泛型需要指定对应的实体类 public interface UserSerivce extends IService<User> { }
在com.augus.service下创建impl包,创建UserServiceImpi,内容如下:
package com.augus.service.impl; import com.augus.mapper.UserMapper; import com.augus.pojo.User; import com.augus.service.UserSerivce; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; //这个实现类需要继承 ServiceImpl泛型需要指定mapper和实体类 @Service public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserSerivce { }
创建测试类:MybatisPlusServiceTest,内容如下:
package com.augus; import com.augus.pojo.User; import com.augus.service.UserSerivce; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.ArrayList; @SpringBootTest public class MybatisPlusServiceTest { @Autowired private UserSerivce userSerivce; @Test public void testGetCount(){ //统计数据量 long count = userSerivce.count(); System.out.println("数据总量为:"+count); } @Test public void testSaveBath(){ /** * 批量插入,由于SQL长度的显示,数据量太大单条SQL无法实行 * 因此批量插入应该实现放在了service层中实现,而不是mapper层中 */ ArrayList<User> users = new ArrayList<>(); for (int i=0;i < 5; i++){ //实例化产生user对象 User user = new User(); //设置属性的值 user.setName("augus"+i); user.setAge(33+i); user.setEmail(i+"122432@qq.com"); //添加数组中 users.add(user); } boolean b = userSerivce.saveBatch(users); System.out.println("插入的行数:"+b); } }

浙公网安备 33010602011771号