MyBatis-Plus (简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。注解就是拓展了开发的功能并保障了代码的灵活性,所以MP的注解,就使代码更加精简和灵活。下面对一部分MP的注解进行介绍:
1、@TableName :用于标识实体类与数据库表的映射关系。可以在实体类上使用,指定对应的数据库表名。
2、@TableId :用于标识实体类的主键字段。可以在主键字段上使用,指定主键生成策略。
3、@TableField :用于标识实体类的字段与数据库表字段的映射关系。可以在实体类字段上使用,指定对应的数据库表字段名。
4、@Version :用于标识实体类的乐观锁字段。可以在乐观锁字段上使用,用于处理并发更新冲突。
5、@EnumValue :用于标识实体类的枚举字段。可以在枚举字段上使用,指定对应的数据库存储值。
6、@TableLogic :用于标识实体类的逻辑删除字段。可以在逻辑删除字段上使用,指定逻辑删除的值。
7、@SqlParser :用于标识实体类的字段是否参与SQL解析。可以在实体类字段上使用。
8、@KeySequence :用于标识实体类的主键序列。可以在实体类上使用。
9、@InsertFill :用于在插入数据时自动填充字段的值。
10、@UpdateFill :用于在更新数据时自动填充字段的值。
11、@SqlParser :用于标识是否参与SQL解析。
12、@SqlStatement :用于指定自定义的SQL语句。
13、@ResultMap :用于指定结果集的映射关系,可以在XML配置文件中使用。
14、@SelectProvider :用于指定动态SQL的提供者。
15、@UpdateProvider :用于指定动态更新SQL的提供者。
16、@DeleteProvider :用于指定动态删除SQL的提供者。
视图化工具:
项目实例:
可以看到,@TableName 注解的值 和视图化工具中的表名相同,@TableId 注解则放在表主键所对应的字段的上面,MP在解析时,会自动将字段识别为主键。 查看两个注解的源码
由 元注解 可知,@Inherited 注解被省略了,这以为着这两个注解不能被子类继承,所以可以看到,上面的项目实例,注解都是在子类上面放着。
先查看 @TableField 注解的源码
由源码可知,当 【数据库字段值去掉下划线和空格符之后转大写】的值与【实体属性名转大写】的值相等,就不需要这个注解。反而言之,在MP中,当这两个值不相等时,或数据库中不包含该字段时,就需要在实体属性名上加上@TableField 注解。AI示例如下:
public class User {
// 普通字段映射
@TableId(type = IdType.AUTO)
private Long id; // 数据库表字段名为 "id"
@TableField(value = "name", exist = true)
private String username; // 数据库表字段名为 "name"
private Integer age; // 数据库表字段名为 "age"
// 非数据库表字段,不参与映射
@TableField(exist = false)
private String password;
// getter 和 setter 省略
}
@Version是Spring Data JPA提供的注解之一,在实体类中加上@Version可以实现乐观锁。具体实用示例如下:
首先,在实体类中加上@Version注解,如下所示:
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
@Version
private Long version;
// 省略getter/setter方法
}
其中,version字段即为乐观锁的版本号。
接着,在更新数据的时候需要加上版本号的限制,否则更新操作将失败。示例代码如下:
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
/**
* 更新用户信息
*
* @param user 用户信息
*/
public void updateUser(User user) {
userRepository.save(user);
}
}
当执行updateUser方法时,如果版本号已经被其他线程更新,会抛出OptimisticLockException异常,从而避免数据冲突。
@EnumValue是一个非常实用的注解,可以在枚举类中定义一个字段,并且将该字段映射为枚举值的值。举个例子,我们可以定义一个枚举类Gender,用于表示性别:
public enum EnumMsg{
SUCCESS(0, "交易成功"),
FAIL(1, "交易失败"),
ERROR(2, "交易异常");
@EnumValue
private final int value;
private final String name;
EnumGsg(int value, String name) {
this.value = value;
this.name = name;
}
public int getValue() {
return value;
}
public String getName() {
return name;
}
}
在这个例子中,我们定义了一个@EnumValue注解,将value字段映射为枚举值的值。比如,SUCCESS枚举值的value属性为0,FAIL枚举值的value属性为1,ERROR枚举值的value属性为2。
有了@EnumValue注解,我们就可以使用枚举值的值来表示枚举值,而不是使用枚举值的名称。比如,我们可以通过以下方式获取MALE对应的枚举值:
int value = EnumMsg.FAIL.getValue(); // value=1
这种方式可以避免使用枚举值的名称造成的拼写错误问题。同时,使用@EnumValue注解还可以简化代码,避免使用switch语句等复杂的结构进行枚举值的比较和匹配。