1、MP简介
MyBatis-Plus(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生
官网:MyBatis-Plus 🚀 为简化开发而生
参考教程:https://baomidou.com
2、关键特性和优势
自动填充:MyBatis-Plus提供了自动填充功能,可以自动填充创建时间、最后修改时间等字段
乐观锁:支持乐观锁,可以避免并发更新时的数据冲突
逻辑删除:支持逻辑删除,通过特定的字段来标记数据是否被删除,而不是真正从数据库中删除数据
自动构建insert
、update
语句:通过MyBatis-Plus的API,可以自动构建插入和更新操作的SQL语句,简化代码编写
自动驼峰命名规则:支持数据库表字段与Java对象属性之间的自动驼峰命名规则映射,减少开发者编写映射语句的工作量
自动处理join
查询:简化了多表关联查询的复杂性,自动处理join
查询的SQL构建。
自动分页:提供了自动分页功能,可以很容易地实现数据的分页查询
3、MP引入步骤
3.1、添加依赖
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!--lombok用来简化实体类-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
3.2、创建实体类并添加注解
mapper层实现BaseMapper接口并指明实体类名称
表示该接口可以对该实体类对应的数据库表进行操作
service层service接口要继承Iservice并指明实体类
serviceimpl实体类要继承serviceimpl指明Mapper层接口和实体类,并实现service接口
3.3、常见注解
用在实体类中
@TableID:标识主键字段
@TableId注解支持两个属性:value,type
type支持的类型:Auto(自增),ASSIGN_ID(雪花唯一算法)
@TableName:标注表名这也是注解的默认属性
@TableField:标明表中字段
属性:value(字段名),exist(是否存在) ,fill(自动填充)
@JsonIgnore:不将该字段返回
@TableLogic:标明该字段是逻辑删除字段isDelete
如果不用注解则要在配置文件中标明
3.4、常见配置
全局id类型
mybatis-plus:
type-aliases-package: com.itheima.mp.domain.po
global-config:
db-config:
id-type: auto # 全局id类型为自增长
MP也是支持XML文件自定义SQL的,配置如下
mybatis-plus:
mapper-locations: "classpath*:/mapper/**/*.xml" # Mapper.xml文件地址,当前这个是默认值。
可以看到默认值是classpath*:/mapper/**/*.xml
,也就是说我们只要把mapper.xml文件放置这个目录下就一定会被加载
3.5、条件构造器
除了新增以外,修改、删除、查询的SQL语句都需要指定where条件。因此BaseMapper中提供的相关方法除了以id
作为where
条件以外,还支持更加复杂的where
条件。、
Service接口
MybatisPlus不仅提供了BaseMapper,还提供了通用的Service接口及默认实现,封装了一些常用的service模板方法。 通用接口为IService
,默认实现为ServiceImpl
自定义service接口继承Iservice
定义serviceimpl继承Iservice实现service接口并在泛型中标明Mapper层和实体类
package com.itheima.mp.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.po.service.IUserService;
import com.itheima.mp.mapper.UserMapper;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
implements IUserService {
}
我们无需自己通过new
的方式来创建Wrapper
,而是直接调用lambdaQuery
和lambdaUpdate
方法
也可以避免了条件的直接写死,可以动态的获取实体类属性,代码更加优雅,健硕性更强
@GetMapping("/list")
@ApiOperation("根据id集合查询用户")
public List<UserVO> queryUsers(UserQuery query){
// 1.组织条件
String username = query.getName();
Integer status = query.getStatus();
Integer minBalance = query.getMinBalance();
Integer maxBalance = query.getMaxBalance();
// 2.查询用户
List<User> users = userService.lambdaQuery()
.like(username != null, User::getUsername, username)
.eq(status != null, User::getStatus, status)
.ge(minBalance != null, User::getBalance, minBalance)
.le(maxBalance != null, User::getBalance, maxBalance)
.list();
// 3.处理vo
return BeanUtil.copyToList(users, UserVO.class);
}
可以发现lambdaQuery方法中除了可以构建条件,还需要在链式编程的最后添加一个list()
,这是在告诉MP我们的调用结果需要是一个list集合。这里不仅可以用list()
,可选的方法有:
-
.one()
:最多1个结果 -
.list()
:返回集合结果 -
.count()
:返回计数结果
MybatisPlus会根据链式编程的最后一个方法来判断最终的返回结果
3.6、静态工具
有的时候Service之间也会相互调用,为了避免出现循环依赖问题,MybatisPlus提供一个静态工具类:Db
,其中的一些静态方法与IService
中方法签名基本一致,也可以帮助我们实现CRUD功能
4、MP个别特性的体现
4.1、数据转换
要让MybatisPlus
处理枚举与数据库类型自动转换,我们必须告诉MybatisPlus
,枚举中的哪个字段的值作为数据库值。 MybatisPlus
提供了@EnumValue
注解来标记枚举属性
被注解标注的字段是以实例的方式进行传值的,且只能传递在枚举类中定义好的实例
能够实现任意数据类型和枚举之间的转换
对一些长的信息字段可以用注解@JsonValue注解来标注,达到将数据以JSon格式来进行传输
字段类型不在是基本数据类型是自己定义的实体类,需使用@TableField注解并添加参数
typefield=JacksonTypeHandler.class处理器
在UserStatus枚举中通过@JsonValue
注解标记JSON序列化时展示的字段
实现多个数据转换成序列化为JSON格式,接收时采用Map,实体类来接收数据
4.2、分页插件
package com.itheima.mp.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
// 初始化核心插件
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
4.3、实体类继承通用实体类
就是将每个表的通用字段抽取出来形成一个实体类,
别的实体类都去继承该类,达到字段的冗余处理
也方便后续对公共字段进行修改