MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window) 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作
开发
从这里开始我将总结Mybatis-plus中的各种API和使用
配置
在开始之前,我们需要先导入Mybatis-plus的依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>最新版本</version>
</dependency>
</dependencies>
和mybatis不同的是,我们不用去xml文件中配置数据库的连接,直接在yml中去配置数据库的连接
这里我就直接拿官网这个了(知道字段是什么意思就行)
spring:
datasource:
driver-class-name: org.h2.Driver
schema: classpath:db/schema-h2.sql
data: classpath:db/data-h2.sql
url: jdbc:h2:mem:test
username: root
password: test
这里我们就像Mybatis一样先写映射文件,不过这里我们的映射使用的更简单
public interface Mapper extends BaseMapper {
}
这样就已经写好了映射,之前我们使用mybaits是将sql语句写在这个映射的下面,现在也是不用的,我们使用一个类用来接收实体类的映射后,调用当中的API就可以实现CRUD,现在这个映射中就继承BaseMapper这个类就可以将大量的CRUD的API导入进来了,不过有些没有的,也可以自己来像写Mybatis一样写在下面,不过基本上已经覆盖了大量SQL
加载完成数据库的连接之后,我们需要在启动类中添加@MapperScan扫描mapper文件
编写一个实体类,存放的就是数据库中的字段,使用lombok简化代码
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
注解讲解
这里的@Data是插件lombok的注解,可以自动的帮助我们生成getter、setter、构造方法,如果你不适用@Data,也可以使用@Getter和@Setter只生成getter和setter方法。
不过这里这样写需要注意一个问题
这里的变量名是必须和SQL中的字段名相同能匹配的,不然是会报错的,如果如果两边的值不一样又想绑定到一起的话,就需要使用我们的注解@TableName、@TableField可以绑定数据库的字段,具体使用如下所示
@Data
@TableName("user")
public class User {
@TableField(value = "id")
private Long id;
@TableField(value = "name")
private String name;
@TableField(value = "age")
private Integer age;
@TableField(value = "email")
private String email;
}
这里的@TableName就绑定了数据库的名称,就不用再去管你这个类的名字是否和数据库表名同名了,并且@TableField也是如此,不过这里绑定的是字段而已。
CRUD
这里我就演示标准的CRUD了,都是根据ID来进行CRUD
public class impl{ //根据ID来查
@Test
public void test1(){
User user = new User();
System.out.println(user.selectById(1L));
}
}
@Test
public void test2(){ //根据ID删除数据
User user = new User();
System.out.println(user.deleteById(1L));
}
@Test
public void test3(){ //先将值设定要修改的,在调用API
User user = new User();
user.setId("1");
user.setEmail("10000");
System.out.println(user.updateById());
}
@Test
public void test4(){ //设置好之后,直接调用API插入
User user = new User();
user.setId("2");
user.setEmail("20000");
System.out.println(user.insert());
}
这就是最基础的CRUD操作,在进行了最基础的CRUD操作之后,下面我将讲解其他的功能
分页
分页这里我就只提供API了,操作都是一样的
IPage page = new Page(1,2) //1是当前页码值,2是每页显示数
page.getCurrent() //获取当前的页码值
page.getSize() //获取当前的每页显示数
page.getPages() //获取当前一共多少页
page.getTotal() //获取当前一共多少条
page.getRecords() //获取数据
这里需要补充的有一点是,直接这样查是查不了的(获取一共多少页和多少条会为0,数据获取出来是全部的数据),解决这个问题,我们需要使用mybatis-plus提供的拦截器,使用拦截器中的分页功能才能解决问题,写一个配置类
public MybatisPlusInterceptor paginationInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
interceptor.addInnerInterceptor(paginationInnerInterceptor);
return interceptor;
这里的代码意思也就是在Mybatis-plus中的拦截器(MybatisPlusInterceptor)中添加了分页功能(PaginationInnerInterceptor)就可以解决掉无法分页的问题,这个分页也就是我们常写SQL中的limit语句。
条件查询
我们在使用SQL的时候通常使用的是where做条件的查询,现在我们在这么多API中也会有代替这个语句的接口,我们常用的就是QueryWrapper和LambdaQueryWrapper两种条件构造器。将QueryWrapper实例之后,调用当中的方法,方法如下
这样就可以实现条件的查询了,示例如下
@Test
public void test5(){ //输出name字段为a的数据
User user = new User();
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name","a");
System.out.println(user.selectList(queryWrapper));
}
而LambdaQueryWrapper只是在QueryWrapper上使用了Lambda表达式简化开发,功能都是相同的,示例如下
@Test
public void test5(){
User user = new User();
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(User::getEmail, "10000");
user.selectList(lambdaQueryWrapper);
}
查询投影
例如我们不需要全部的数据,只需要当中的部分字段就可以了,就进行如下的操作
使用的是QueryWrapper来查询的时候,中间限制查询的字段时,使用字符串来解决
queryWrapper.select("id","name","age");
但是如果是使用的lambdaQuery的时候,就应该使用lambda的形式
qw.select(user::id,user::name,user::age);
这里补充一个我们常用的模糊匹配
模糊匹配中调用qw.like
qw.likeleft和qw.likeright是用来做百分号位置的,left就是百分号在前,right就是百分号在后
配置逻辑删除
这个是我们在企业开发中常使用的,因为它不具有实质性的删除,而是给数据做了标记
配置逻辑删除,可以通过@TableLogic来进行标记属性中的delval代表删除的状态码,val代表默认的没有删除的状态码,并且我们也可以通过全局配置的这种情况来进行配置,我们可以通过mybatis-plus:global-config:db-config:的相同的属性名来进行配置不同的状态码,需要注意的是,开启了逻辑删除以后,执行delete语句将会变为update修改语句。示例如下
@TableLogic(delval = "1",value = "0")
private String work;
这样就表示当状态码为1时代表数据删除了,但是数据是存在的,只是查不出来,因为调用删除的时候会默认查的是状态码为0的,只用配置了已删除和未删除的状态码就可以自动的标记文件是否删除,一定要注意,这时候的数据删除会变成修改的语句,不会将数据删除的!!!
这里补充一个多条数据删除的
多条删除deleteBatchIds(list),当中需要的是一个List
ID自增长
我们希望插入数据的时候,ID能够自动添加,现在我们使用Mybatis-plus的API也可以实现,使用注解@TableID中的type属性的IdType就可以有几种解决方案
public enum IdType {
AUTO(0),
NONE(1),
INPUT(2),
ASSIGN_ID(3),
ASSIGN_UUID(4);
private final int key;
private IdType(int key) {
this.key = key;
}
public int getKey() {
return this.key;
}
}
这是当中的源码,我们在源码中可以看到枚举中有5中解决的方案,我们常用的就是AUTO自动增长一个整型,NONE不开启自动增长,INPUT由用户决定ID,ASSIGN_ID由雪花算法自动生成一个16位Long型的ID。
乐观锁
乐观锁:业务并发带来的问题,注解@Version代表乐观锁,其实乐观锁就是在数据中添加一个新的version字段,该字段在修改后int类型的数据是会自动增长的,别的用户是不能够同时访问同一个数据的,所以这也解决了并发的问题。使用的依赖如下所示
@Bean
public OptimisticLockerInnerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInnerInterceptor();
}
}