接着上期内容:前言技术之Mybatis Plus_爱嘤斯塔的博客-CSDN博客
一、mybatis-plus的含义
升级版的mybatis,目的是让mybatis更易于使用, 用官方的话说“为简化而生”
二、演示
1、修改数据库,添加字段注释
2、主键生成策略
雪花算法,默认的主键生策略,如果需要保存的实体对象中没有指定的主键值,则默认使用雪花算法来生成。
自增ID:
数据库的字段必须是配置了自增
对应的实体的主键字段加入自增注解: @TableId(type = IdType.AUTO)
其他类型:
public enum IdType {
AUTO(0),
//自动增长
NONE(1), //未设置主键
INPUT(2), //由用户手动输入
ASSIGN_ID(3), //雪花算法
ASSIGN_UUID(4); //排除到下划线的UUID,32位长度
private final int key;
private IdType(int key) {
this.key = key;
}
public int getKey() {
return this.key;
}
}
在实体类中标注:
@TableId(value = "id",type = IdType.AUTO)
private Long id;
测试类:
System.out.println(UUID.randomUUID());
一般id不需-,去掉:
System.out.println(UUID.randomUUID().toString().replace("-",""));
3、更新
通过主键更新
可以通过mapper层调用方法,也可使用service层调用
若逻辑层过于简单,就不需要在mapper层内定义方法,就可以直接使用service层
若进行业务处理,则就使用mapper层。
在mapper层调用查询的方法是select,增加是insert
在service层调用查询的方法是get,增加是save
测试类:
package com.lv.plus;
import com.lv.plus.mapper.UserMapper;
import com.lv.plus.pojo.User;
import com.lv.plus.service.IUserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.UUID;
@SpringBootTest
class PlusApplicationTests {
@Autowired
private UserMapper mapper;
@Autowired
private IUserService service;
@Test
void contextLoads() {
User u=new User().setId(1L).setName("aa");
int i=mapper.updateById(u);
System.out.println(i);
boolean b=service.updateById(u);
System.out.println(b);
}
}
数值改变:
4、自动填充
在数据表的设计中,经常需要加一些字段,如:创建时间,最后修改时间等,此时可以使用mybatis-plus来帮我们进行自动维护
在自动填充有两种方式:
①、 通过数据库完成自动填充
实体类:
@Data public class User { @TableId(type = IdType.AUTO) private int id; private String name; private Integer age; private String email; //在代码中同步加入创建时间和最后修改时间的维护 private Date createTime; private Date lastModifiedTime; }
完成后可以通过新增或更新
②、使用程序完成自动填充
将数据库中的自动维护功能取消:
第一步:实体类中加入注解
//表明在插入时自动维护字段 @TableField(fill = FieldFill.INSERT) private Date createTime; //表明在插入和更新时自动维护字段 @TableField(fill = FieldFill.INSERT_UPDATE) private Date lastModifiedTime;
第二步:编写处理类
// 不要忘了处理器是spring的组件 @Component public class AutoFillHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName("createTime",new Date(), metaObject); this.setFieldValByName("lastModifiedTime",new Date(), metaObject); } @Override public void updateFill(MetaObject metaObject) { //this.setFieldValByName("createTime",new Date(), metaObject); this.setFieldValByName("lastModifiedTime",new Date(), metaObject); } }
完成后可以通过新增或更新
5、乐观锁
含义:当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式(来自官方文档):
取出记录时,获取当前version
更新时,带上这个version
执行更新时, set version = newVersion where version = oldVersion
如果version不对,就更新失败
①、配置示例
在数据库表中加入version字段,表示数据版本号
修改实体类,在使用类中加入对应的version字段,并使用是乐观锁:
@TableField("version")
// 乐观锁
@Version
private int version;
②、配置乐观锁
package com.lv.plus.configurator;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
③、测试
package com.lv.plus;
import com.lv.plus.mapper.UserMapper;
import com.lv.plus.pojo.User;
import com.lv.plus.service.IUserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.UUID;
@SpringBootTest
class PlusApplicationTests {
@Autowired
private UserMapper mapper;
@Autowired
private IUserService service;
@Test
void contextLoads() {
User u1=mapper.selectById(1L);
User u2=mapper.selectById(1L);
u1.setName("晚柠");
u2.setName("爱嘤斯塔");
int i1=mapper.updateById(u1);
int i2=mapper.updateById(u2);
System.out.println(i1+"-----"+i2);
}
}
第一次修改成功,第二次未被修改:
7、条件查询
批量查询多个对象:
System.out.println(mapper.selectBatchIds(Arrays.asList(2L,3L,4L)));
@Test
public void testSelectByMap() {
//使用map进行查询
Map<String, Object> map = new HashMap<>();
map.put("name", "Tom");
map.put("age", 28);
List<User> users = userMapper.selectByMap(map);
users.forEach(t-> System.out.println(t));
}
8、分页查询
①、分页配置
在配置器MybatisPlusConfig中加入配置拦截器:
package com.lv.plus.configurator;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
// 加入分页拦截器
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
测试类:
package com.lv.plus;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lv.plus.mapper.UserMapper;
import com.lv.plus.pojo.User;
import com.lv.plus.service.IUserService;
import org.apache.ibatis.jdbc.Null;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays;
import java.util.UUID;
@SpringBootTest
class PlusApplicationTests {
@Autowired
private UserMapper mapper;
@Autowired
private IUserService service;
@Test
void contextLoads() {
mapper
.selectPage(Page.of(1l,2L),null)
.getRecords()
.forEach(System.out::println);
}
}
9、逻辑删除逻辑删除
物理删除使用起来比较简单,仿照查询功能即可,不再赘述。
什么是逻辑删除?
即:标记删除,并不是真的从数据库中删除,而是做个删除标记,在查询时,过滤掉标记为删除的记录即可。
①、数据库表结构调整
加字段:
②、修改实体类
//标记该字段为逻辑删除字段
@TableLogic
private int deleted;
③、在application.yml中加入如下配置
mybatis-plus:
global-config:
db-config:
#逻辑删除字段名
logic-delete-field: deleted
# 1表示逻辑删除
logic-delete-value: 1
# 0 表示未删除
logic-not-delete-value: 0
测试:
mapper.deleteById(2L);
状态发生改变:
10、Wrapper
用于构造查询条件
QueryWrapper与updateWrapper的区别:
updateWrapper还可以设置修改的值
测试类:
@Test
void contextLoads() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
// likeRight查询右边以T开头的,likeLeft以T结尾的
wrapper.likeRight("name", "T")
.eq("age", 28);
// lt代表<,gt代表>,le代表<=
}
@Test
public void testUpdateWrapper() {
UpdateWrapper u = new UpdateWrapper();
//u.set("name", "TT");
u.eq(true, "id", 6L);
User user = userMapper.selectById(6L);
//user = new User();
user.setName("TTT");
userMapper.update(user, u);
}