[Mybatis-Plus笔记] MybatisPlus-05-id生成策略,多数据操作,逻辑删除
一、id生成策略
在实体类的 id 属性上注解 @TableId 并指定 type 属性,可以设置 id 生成策略,常用的有下面几种:
1. 自增id(type = IdType.AUTO)
注解 @TableId(type = IdType.AUTO)
表示为自增 id,需要表结构也将 id 设为自增主键
自增 id 会按照顺序递增生成 id,插入数据时可以不带 id 值,也可以指定 id 值,但不能是已有的 id
实体类:
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tbl_user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
}
测试类:
@SpringBootTest
public class MybatisPlusTest {
@Autowired
UserMapper userMapper;
@Test
void testInsert() {
User user = new User(null, "Alice", 17, "alice@outlook.com");
userMapper.insert(user);
}
}
Mybatis-Plus 日志:
==> Preparing: INSERT INTO tbl_user ( name, age, email ) VALUES ( ?, ?, ? )
==> Parameters: Alice(String), 17(Integer), alice@outlook.com(String)
<== Updates: 1
2. 输入id(type = IdType.INPUT)
注解 @TableId(type = IdType.INPUT)
表示需要插入数据时需要指定 id 值
通常表结构中 id 不是自增主键,如果是自增的,那么无需指定 id 值也可正常插入,效果和 IdType.AUTO 相同
实体类 id 字段:
// 省略了无关部分
@TableId(type = IdType.INPUT)
private Long id;
测试方法:
@Test
void testInsert() {
User user = new User(37L, "Alice", 17, "alice@outlook.com");
userMapper.insert(user);
}
Mybatis-Plus 日志:
==> Preparing: INSERT INTO tbl_user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
==> Parameters: 37(Long), Alice(String), 17(Integer), alice@outlook.com(String)
<== Updates: 1
2. 雪花算法生成id(type = IdType.ASSIGN_ID)
注解 @TableId(type = IdType.ASSIGN_ID)
,表示由 Mybatis-Plus 自动生成 id 并填入数据库
插入数据时不指定 id 值便会使用雪花算法自动生成的 id,若指定了 id 则不会
实体类 id 字段:
// 省略了无关部分
@TableId(type = IdType.ASSIGN_ID)
private Long id;
测试方法:
@Test
void testInsert() {
User user = new User(null, "Alice", 17, "alice@outlook.com");
userMapper.insert(user);
}
Mybatis-Plus 日志:
==> Preparing: INSERT INTO tbl_user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
==> Parameters: 1571399057521795074(Long), Alice(String), 17(Integer), alice@outlook.com(String)
<== Updates: 1
雪花算法所生成的是一个 64 位的长整形,所以 id 通常用 Long 类型
对应生成的长整型 id,简单来说从左到右分别为 1 位符号位,41 位时间戳(差值),10 位机器码,12 位序列号
关于雪花算法,更详细的内容推荐阅读这篇文章:雪花算法(SnowFlake)
二、多数据操作(查询与删除)
1. 按多个 id 查询
使用 selectBatchIds() 方法实现,将一个 List 作为参数传入,里面存放着多个 id
测试方法:
@Test
void testSelectBatchIds() {
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
ids.add(3);
List<User> users = userMapper.selectBatchIds(ids);
System.out.println(users);
}
Mybatis-Plus 日志:
==> Preparing: SELECT id,name,age,email FROM tbl_user WHERE id IN ( ? , ? , ? )
==> Parameters: 1(Integer), 2(Integer), 3(Integer)
<== Columns: id, name, age, email
<== Row: 1, Pauline Cole, 20, paulic59@icloud.com
<== Row: 2, Tao Chi Yuen, 17, chiyuentao@icloud.com
<== Row: 3, Xu Lan, 23, xul@hotmail.com
<== Total: 3
2. 按多个 id 删除
使用 deleteBatchIds() 方法实现,将一个 List 作为参数传入,里面存放着多个 id
测试方法:
@Test
void testUpdateBatchIds() {
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
ids.add(114514); // 不存在此 id
int ret = userMapper.deleteBatchIds(ids);
System.out.println(ret);
}
Mybatis-Plus 日志:
==> Preparing: DELETE FROM tbl_user WHERE id IN ( ? , ? , ? )
==> Parameters: 1(Integer), 2(Integer), 114514(Integer)
<== Updates: 2
三、逻辑删除
逻辑删除指只对需要删除的数据打上已被删除的标记,而不真正删除库中的相关数据
做法如下:
1. 在表中设置标记字段
例如下脚本建立表:
DROP TABLE IF EXISTS `tbl_user`;
CREATE TABLE `tbl_user` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(30) COMMENT '姓名',
`age` int COMMENT '年龄',
`email` varchar(50) COMMENT '邮箱',
`deleted` int DEFAULT 0 COMMENT '逻辑删除标记,默认为 0 表示未被删除',
PRIMARY KEY (`id`)
)
2. 实体类中注解 @TableLogic
@TableLogic 注解中有两个属性,value 为默认值,表示未删除,delval 为表示已删除的值
@Data
@TableName("tbl_user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
@TableLogic(value = "0", delval = "1")
private Integer deleted;
}
3. 效果查看
此时执行的任何操作都会加上 deleted = 0 的条件对数据进行过滤
尝试查询所有行,测试类如下:
@SpringBootTest
public class MybatisPlusTest {
@Autowired
UserMapper userMapper;
@Test
void testSelectAll() {
List<User> users = userMapper.selectList(null);
System.out.println(users);
}
}
Mybatis-Plus 日志:
==> Preparing: SELECT id,name,age,email,deleted FROM tbl_user WHERE deleted=0
==> Parameters:
<== Columns: id, name, age, email, deleted
<== Row: 1, Arthur Bennett, 22, bennettart@yahoo.com, 0
<== Row: 2, Valerie Grant, 24, gravalerie@yahoo.com, 0
<== Row: 3, Thelma Powell, 19, powellthel@icloud.com, 0
<== Total: 3
可以看出 sql 语句后跟了 WHERE deleted=0
的条件
再尝试按 id 删除操作,测试类如下:
@SpringBootTest
public class MybatisPlusTest {
@Autowired
UserMapper userMapper;
@Test
void testDeleteById() {
long id = 2;
int ret = userMapper.deleteById(id);
System.out.println(ret);
}
}
Mybatis-Plus 日志:
==> Preparing: UPDATE tbl_user SET deleted=1 WHERE id=? AND deleted=0
==> Parameters: 2(Long)
<== Updates: 1
发现此时执行的是 UPDATE 操作而不是 DELETE 操作,只将 deleted 标记值从 0 改为 1 而没有删除任何数据