CRUD
insert
insert应该主要关注mybatis-plus对主键字段的处理
主键生成策略
拓展:主键生成的常见策略
- UUID
- 自增ID
- 雪花算法
- 使用redis生成
雪花算法:
SnowFlake算法生成id的结果是一个64bit大小的整数,适用于分布式系统,它的结构如下图:
图像来源:https://www.jianshu.com/p/2a27fbd9e71a
@TableId
使用@TableId
可以指定实体类对应的主键字段
@Data()
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "user")
public class User {
@TableId()
private Long id;
private String name;
private Integer age;
private String email;
}
@TableId
可以配置主键对应的数据库字段名(value
)和主键生成类型(type
)
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|---|---|---|---|
value | String | 否 | “” | 主键字段名 |
type | Enum | 否 | IdType.NONE | 指定主键类型 |
IdType枚举
值 | 描述 |
---|---|
AUTO | 数据库 ID 自增 |
NONE | 无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT) |
INPUT | insert 前自行 set 主键值 |
ASSIGN_ID | 分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator 的方法nextId (默认实现类为DefaultIdentifierGenerator 雪花算法) |
ASSIGN_UUID | 分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator 的方法nextUUID (默认 default 方法) |
ID_WORKER | 分布式全局唯一 ID 长整型类型(please use ASSIGN_ID ) |
UUID | 32 位 UUID 字符串(please use ASSIGN_UUID ) |
ID_WORKER_STR | 分布式全局唯一 ID 字符串类型(please use ASSIGN_ID ) |
update
动态SQL
使用诸如 updateById
这些方法时,,mysql-plus会自动生成动态的sql语句去执行。
乐观锁插件
OptimisticLockerInnerInterceptor
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:取出记录时,获取当前 version
更新时,带上这个 version
更新时, set version = newVersion where version = oldVersion
如果 version 不对,就更新失败
配置:
- 配置插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
- 在实体类的字段上加上
@Version
注解
@Version
private Integer version;
说明:
- 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
- 整数类型下
newVersion = oldVersion + 1
newVersion
会回写到entity
中- 仅支持
updateById(id)
与update(entity, wrapper)
方法- 在
update(entity, wrapper)
方法下,wrapper
不能复用!!!
select
-
selectList()
查询所有 -
selectBatchIds()
查询批量对象 -
selectById()
使用id查询一个对象
条件查询
selectByMap
Map<String, Object> map=new HashMap<>();
map.put("name","lisi");
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
分页查询
拓展:分页查询的实现方式
使用limit语句实现
使用pageHelper 第三方库
MyBatisPlus内置了分页查询功能
编码
- 添加一个分页Interceptor
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
- 使用mapper
@Test
public void testPageSelect(){
//第3页,每页4条记录
final Page<User> userPage = new Page<>(3,4);
userMapper.selectPage(userPage, null);
System.out.println("userPage.getTotal() = " + userPage.getTotal());
System.out.println("userPage.getPages() = " + userPage.getPages());
System.out.println("userPage.getCurrent() = " + userPage.getCurrent());
System.out.println("userPage.getSize() = " + userPage.getSize());
userPage.getRecords().forEach(System.out::println);
}
delete
基本删除
基本删除操作用法和select
相似,如通过id删除、批量删除、条件删除等,这里不再赘述。
逻辑删除
物理删除和逻辑删除
物理删除:从数据库中直接删除数据
逻辑删除:数据没有从数据库中直接删除,而是使用一个字段来删除,例如,让
deleted
字段的值为1表示删除。
逻辑删除需要在数据库表中添加一个字段,如 deleted
步骤1:配置
mybatis-plus:
global-config:
db-config:
logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
步骤2:实体类字段上添加注解@TableLogic
@TableLogic
private Integer deleted;
完成上面两步之后就可以直接使用mapper类进行逻辑删除操,查询的时候也会过滤掉逻辑删除的记录。