mybatisplus
一、添加依赖
springboot父依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
<relativePath/>
</parent>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
二、条件构造器
1、QueryWrapper查询
QueryWrapper<实体类> queryWrapper = new QueryWrapper<>();
List<Long> ids= new ArrayList<>();
queryWrapper.in("id",ids); // 可入参数组查询
queryWrapper.and(wrapper->wrapper.eq("数字库字段",入参数据)); //可进行嵌套子查询
2、时间段查询
// 查询开始时间
String startTime = "2022-04-19"; //yyyy-MM-dd HH:mm:ss
queryWrapper.apply("UNIX_TIMESTAMP(start_time)>=UNIX_TIMESTAMP('" + startTime + "')");
//queryWrapper.ge("start_time",startTime);
// 结束时间
String endTime = "2022-04-20"; //yyyy-MM-dd HH:mm:ss
queryWrapper.apply("UNIX_TIMESTAMP(end_time)<=UNIX_TIMESTAMP('" + endTime + "')");
//queryWrapper.le("end_time",endTime);
// 备注:存入数据库的时间格式,和查询时间格式必须统一
3、condition(动态组装查询条件)
查询名字中包含n,年龄大于10且小于20的用户,查询条件来源于用户输入,是可选的
/**
* 使用if语句动态判断
*/
@Test
public void test1() {
//定义查询条件,有可能为null(用户未输入)
String name = null;
Integer ageBegin = 10;
Integer ageEnd = 20;
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
if(StringUtils.isNotBlank(name)){
queryWrapper.like("name","n");
}
if(ageBegin != null){
queryWrapper.ge("age", ageBegin);
}
if(ageEnd != null){
queryWrapper.le("age", ageEnd);
}
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
使用带condition参数的重载方法构建查询条件,简化代码的编写
@Test
public void test1Condition() {
//定义查询条件,有可能为null(用户未输入)
String name = null;
Integer ageBegin = 10;
Integer ageEnd = 20;
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper
.like(StringUtils.isNotBlank(name), "name", "n")
.ge(ageBegin != null, "age", ageBegin)
.le(ageEnd != null, "age", ageEnd);
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
4、LambdaQueryWrapper
@Test
public void test2() {
//定义查询条件,有可能为null(用户未输入)
String name = null;
Integer ageBegin = 10;
Integer ageEnd = 20;
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
//避免使用字符串表示字段,防止运行时错误
//User 是用户实体类
.like(StringUtils.isNotBlank(name), User::getName, "n")
.ge(ageBegin != null, User::getAge, ageBegin)
.le(ageEnd != null, User::getAge, ageEnd);
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
三、插件
1、mybatisplus分页查询
1.1、配置类
@Configuration
@MapperScan("com.lyh.mybatisplus.mapper")
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
1.2、Controller层
@GetMapping("/list")
@ApiOperation(value = "按条件分页查询")
public R list(@ApiParam(value = "当前页码", required = true) Long current,
@ApiParam(value = "每页记录数", required = true) Long size,
@ApiParam("查询对象条件") XXXVO xxxVO) {
//分页参数
Page<KnowledgeData> page = new Page<>(current, size);
//调用service层查询
IPage<实体类> pageMode = knowledgeDataService.selectPage(page, xxxVO);
//分页查询 获取返回数据
List<实体类> dataList = pageMode.getRecords();
//获取查询数据总记录数
long total = pageMode.getTotal();
HashMap<Object, Object> map = new HashMap<>();
map.put("total", total);
map.put("data", dataList);
return R.data(map);
}
1.3、service层
public IPage<实体类> selectPage(Page<实体类> page, XXXVO xxxVO) {
QueryWrapper<实体类> queryWrapper = new QueryWrapper<>();
//中间判断 加查询条件
Page<实体类> selectPage = baseMapper.selectPage(page, queryWrapper);
return selectPage;
}
1.3、自定义的 mapper#method 使用分页
UserMapper.java中定义接口方法
/**
* 查询 : 根据年龄查询用户列表,分页显示
*
* @param page 分页对象,xml中可以从里面进行取值,传递参数 Page 即自动分页,必须放在第一位
* @param age 年龄
* @return 分页对象
*/
IPage<User> selectPageByPage(Page<?> page, Integer age);
自定义UserMapper.java.xml
<select id="selectPageByPage" resultType="com.lyh.mybatisplus.entity.User">
SELECT id,name FROM user WHERE age > #{age}
</select>
2、乐观锁
2.1、添加配置
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
2.2、在实体类的字段上加上@Version注解
@Version
private Integer version;
2.3、说明
-
**例子:**假设两个同时执行数据更新操作,会造成只有一个执行成功,另一个会被覆盖。
说明: -
支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
整数类型下 newVersion = oldVersion + 1
newVersion 会回写到 entity 中
仅支持 updateById(id) 与 update(entity, wrapper) 方法
在 update(entity, wrapper) 方法下, wrapper 不能复用!!!
四、常用注解
1、@TableName
@TableName(value = "t_user") //对应数据库中表的名字
public class User {
}
2、@TableId
@TableId(value = "uid") //映射数据表中的列名
private String id;
// 注意:当对象的id被明确赋值时,不会使用雪花算法
@TableId(type = IdType.ASSIGN_ID) //雪花算法策略生成数据id
private Long id;
@TableId(type = IdType.AUTO) //使用数据库的自增策略
private Long id;
3、@TableField(可配置自动填充时间)
@TableField(value = "name") //映射数据表中的列名
private String name;
自动填充表数据:创建时间、更新时间
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
自动填充时间的处理类MyMetaObjectHandler.java
实现元对象处理器接口 -> 创建handler包,创建MyMetaObjectHandler类
package com.lyh.mybatisplus.handler;
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}
4、@TableLogic
逻辑删除
- 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据
- 逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录
使用场景:可以进行数据恢复
4.1、数据库中创建逻辑删除状态列
4.2、实体类中添加逻辑删除属性
@TableLogic
@TableField(value = "is_deleted")
private Integer deleted;