MyBatis-Plus常用注解
# 常用注解
# 1. 注解的使用规则
在使用 MyBatis-Plus 时,是否必须要加注解取决于具体的功能需求。MyBatis-Plus 提供了一些注解来简化开发工作和增强功能,但并不是所有情况下都必须使用这些注解。下面详细说明:
# 1. 基础 CRUD 操作(不需要注解)
如果你只是使用 MyBatis-Plus 的基础 CRUD 功能,并且实体类的字段和数据库表的字段名是完全对应的,那么你不需要额外加任何注解。MyBatis-Plus 会根据约定自动处理这些操作。
public class User {
private Long id;
private String username;
private String password;
// Getters and Setters
}
2
3
4
5
6
在这种简单的场景下,MyBatis-Plus 可以通过默认配置完成常见的增删改查操作,注解是可选的。
# 2. 特定需求下需要使用注解
在一些特定场景下,MyBatis-Plus 提供的注解可以帮助你实现更加灵活的功能:
@TableName
:当实体类名与数据库表名不一致时,使用此注解指定表名。@TableId
:用于指定主键字段,并设置主键生成策略。@TableField
:当字段名与数据库列名不一致时,可以使用此注解自定义映射关系。@TableLogic
:实现逻辑删除功能。@Version
:实现乐观锁功能。@TableField(fill = FieldFill.INSERT)
:实现字段的自动填充(如创建时间、更新时间)。
这些注解是为了满足一些高级场景和特定需求,如果你的项目中有这些需求,那么你就需要使用这些注解。
小结
MyBatis-Plus 并不是强制要求你在实体类中使用注解。对于基础功能,如果遵循了约定(如字段名和表名一致),注解是可选的。如果你有特定需求或复杂场景,需要 MyBatis-Plus 提供的高级功能,那么你可以使用相关注解来配置。这些注解只是提供了更多的灵活性,但并不是必须的。
# 2. @TableName
经过以上的测试,在使用 MyBatis-Plus 实现基本的 CRUD 时,我们并没有指定要操作的表,只是在 Mapper 接口继承 BaseMapper 时,设置了泛型 User,而操作的表为 user 表,由此得出结论,MyBatis-Plus 在确定操作的表时,由 BaseMapper 的泛型决定,即实体类型决定,且默认操作的表名和实体类型的类名一致。
# 2.1 引出问题
若实体类类型的类名和要操作的表的表名不一致,会出现什么问题?
我们将表
user
更名为t_user
,测试查询功能程序抛出异常,Table 'mybatis_plus.user' doesn't exist,因为现在的表名为
t_user
,而默认操作的表名和实体类型的类名一致,即user
表
# 2.2 解决问题
# a、使用注解解决问题
在实体类类型上添加
@TableName("t_user")
,标识实体类对应的表,即可成功执行 SQL 语句
@Data
@TableName("t_user")
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
2
3
4
5
6
7
8
# b、使用全局配置解决问题
在开发的过程中,我们经常遇到以上的问题,即实体类所对应的表都有固定的前缀,例如
t_
或tbl_
此时,可以使用 MyBatis-Plus 提供的全局配置,为实体类所对应的表名设置默认的前缀,那么就不需要在每个实体类上通过@TableName 标识实体类对应的表
mybatis-plus:
global-config:
db-config:
# 设置实体类所对应的表的统一前缀
table-prefix: t_
2
3
4
5
# 3. @TableId
经过以上的测试,MyBatis-Plus 在实现 CRUD 时,会默认将 id 作为主键列,并在插入数据时,默认基于雪花算法的策略生成 id
# 3.1 引出问题
若实体类和表中表示主键的不是 id,而是其他字段,例如 uid,MyBatis-Plus 会自动识别 uid 为主键列吗?
我们实体类中的属性
id
改为uid
,将表中的字段id
也改为uid
,测试添加功能程序抛出异常,Field 'uid' doesn't have a default value,说明 MyBatis-Plus 没有将
uid
作为主键赋值
# 3.2 解决问题
在实体类中 uid 属性上通过
@TableId
将其标识为主键,即可成功执行 SQL 语句
@Date
public class User {
@TableId
private Long uid;
private String name;
private Integer age;
private String email;
}
2
3
4
5
6
7
8
# 3.3 @TableId 的 value 属性
若实体类中主键对应的属性为 id,而表中表示主键的字段为 uid,此时若只在属性 id 上添加注解@TableId,则抛出异常Unknown column 'id' in 'field list',即 MyBatis-Plus 仍然会将 id 作为表的主键操作,而表中表示主键的是字段 uid 此时需要通过@TableId 注解的 value 属性,指定表中的主键字段,
@TableId("uid")
或@TableId(value="uid")
# 3.4 @TableId 的 type 属性
type 属性用来定义主键策略:默认雪花算法
常用的主键策略:
值 | 描述 |
---|---|
IdType.ASSIGN_ID(默认) | 基于雪花算法的策略生成数据 id,与数据库 id 是否设置自增无关 |
IdType.AUTO | 使用数据库的自增策略,注意,该类型请确保数据库设置了 id 自增, |
配置全局主键策略:
#MyBatis-Plus相关配置
mybatis-plus:
configuration:
#配置日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
#配置mp的主键策略为自增
id-type: auto
# 设置实体类所对应的表的统一前缀
table-prefix: t_
2
3
4
5
6
7
8
9
10
11
MyBatis Plus支持多种ID生成策略,并且不仅仅是自增策略(IdType.AUTO
)可以实现ID的回填。几乎所有的ID生成策略都支持自动回填ID到Java对象的对应字段中。下面是MyBatis Plus支持的一些主要ID生成策略及其说明:
AUTO
(数据库ID自增): 如果数据库列是自增的,使用这个策略,插入记录后,MyBatis Plus会自动查询数据库生成的ID并回填到Java对象的ID属性中。NONE
(无状态): 这个策略不会自动生成ID,ID需要在插入前手动赋值。INPUT
(手动输入): 类似于NONE
,需要在插入前手动赋值ID,如果没有赋值,就会抛出异常。ASSIGN_ID
(分配ID): 使用雪花算法生成ID。对于Long
类型的字段,如果在插入前没有设置ID,则MyBatis Plus会自动生成ID并回填。ASSIGN_UUID
(分配UUID): 自动生成UUID字符串作为ID。对于String
类型的字段,如果在插入前没有设置ID,MyBatis Plus会自动生成UUID并回填。ID_WORKER
(分布式全局唯一ID,雪花算法): 自动生成ID,适用于Long
类型的字段。ID_WORKER_STR
(分布式全局唯一ID字符串,雪花算法): 自动生成ID,适用于String
类型的字段。UUID
: 自动生成UUID,适用于String
类型的字段。
# 4. @TbaleField
经过以上的测试,我们可以发现,MyBatis-Plus 在执行 SQL 语句时,要保证实体类中的属性名和表中的字段名一致
如果实体类中的属性名和字段名不一致的情况,会出现什么问题呢?
# 4.1 情况一
若实体类中的属性使用的是驼峰命名风格,而表中的字段使用的是下划线命名风格
例如实体类属性userName
,表中字段user_name
此时 MyBatis-Plus 会自动将下划线命名风格转化为驼峰命名风格
相当于在 MyBatis 中配置
# 4.2 情况二
若实体类中的属性和表中的字段不满足情况 1
例如实体类属性
name
,表中字段username
此时需要在实体类属性上使用
@TableField("username")
设置属性所对应的字段名
public class User {
@TableId("uid")
private Long id;
@TableField("username")
private String name;
private Integer age;
private String email;
}
2
3
4
5
6
7
8
# 5. @TableLogic
# 5.1 逻辑删除
物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据
逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录
使用场景:可以进行数据恢复
# 5.2 实现逻辑删除
数据库中创建逻辑删除状态列,设置默认值为 0
实体类中添加逻辑删除属性
测试删除功能,真正执行的是修改
public void testDeleteById(){ int result = userMapper.deleteById(1527472864163348482L); System.out.println(result > 0 ? "删除成功!" : "删除失败!"); System.out.println("受影响的行数为:" + result); }
1
2
3
4
5此时执行查询方法,查询的结果为自动添加条件
is_deleted=0