一、前言
Mybatis-Plus是一个在Mybatis基础上进行增强的ORM框架,提供了许多便捷的注解来简化数据库操作。本文将介绍Mybatis-Plus常用的注解以及它们的使用方法。
二、常用注解
2.1、@TableName
@TableName注解用于指定实体类对应的数据库表名。使用该注解可以省去手动编写SQL语句的繁琐过程。
实例:表名为 db_user,对应的实体类 User
cpp
@TableName(value = "db_user")
public class User {
// 实体类字段
}
2.2、@TableId
@TableId注解用于标识实体类的主键字段。Mybatis-Plus支持多种主键生成策略,如自增、UUID等。通过type
type的值 | 描述 |
---|---|
AUTO | 数据库ID自增 |
NONE | 无状态,该类型为未设置主键类型 |
INPUTE | insert 前自行set主键值 |
ASSIGN_ID | 分配ID(主键类型为Number(Long或Integer)或String,使用接口IdentifierGenerator 的方法 nextId(默认实现类为DefaultIdentifierGenerator 雪花算法)) |
ASSIGN_UUID | 分配UUID,主键类型为String,使用接口IdentifierGenerator 的方法nextUUID(默认default方法) |
ID_WORKER | 分布式全局唯一ID,长整型类型 |
UUID | 32位UUID字符串 |
ID_WORKER_STR | 分布式全局唯一ID,字符串类型 |
比如我们常用的自增主键,或者通过指定id,默认使用微博开源的雪花算法生成id,全局唯一且自增id,即:
@TableId(type = IdType.AUTO)
@TableId(type = IdType.ASSIGN_ID)
实例:
cpp
@TableId(value = "id", type = IdType.AUTO)
private Long id;
2.3、@TableField
@TableField注解用于标识实体类字段与数据库表字段的映射关系。通过该注解,可以指定字段名、是否为插入和更新字段等。
注解里的属性说明:
属性 | 备注 |
---|---|
value | 通过设置该值,对应到数据库表的字段名。 |
condition | 设定值,进而是否开启如模糊查询。 |
exist | 主要指明字段在不在数据库表中,如果 false 则不在数据库表中。 |
select | 注明查到的字段是否要出现在返回结果中,某些场景中,如 User 表中,可能有 password ,对于这种敏感的字段,是不是可以不用返回呢。 |
fill | 这里涉及自动填充,在哪些场景中会用到呢,如 插入、更新、更改的时间,我们希望自动填入,其原理其实也是通过设置实体的值,进而达到自动填入的功能。 |
fill填充的时机:
值 | 描述 |
---|---|
DEFAULT | 默认不处理 |
INSERT | 插入时填充字段 |
UPDATE | 更新时填充字段 |
INSERT_UPDATE | 插入和更新时填充字段 |
如果设置了该 fill 属性,则我们需要去实现或者继承 MetaObjectHandler 接口:
2.4、@EnumValue
这里的使用上,我们需要加到会在数据库表中显示的字段上,比如我们的实体类:
GenderEnum 是一个枚举类:
cpp
package com.example.springbootmybatisplusdemo.entity;
import com.baomidou.mybatisplus.annotation.EnumValue;
public enum GenderEnum {
Male(1, "Male"),
Female(0, "Female");
@EnumValue
private final int code;
private final String desc;
GenderEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
}
通过上述的配置,我们就可以在设置 gender 字段时,通过 GenderEnum 枚举类给定 Male或者Female,最后写入数据库表时,实际是写入的 code 的值,注意我们声明的 1 -> Male,0 -> Female,所以在数据库表中,gender 实际填入的值是 0/1。
2.5、@TableLogic
逻辑删除
物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据
逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为"被删除状态",之后在数据库中仍旧能看到此条数据记录
实例:
cpp
@TableLogic
@TableField(value = "is_deleted")
private Integer deleted;
2.6、@Version
乐观锁
step1:数据库中增加商品表
cpp
CREATE TABLE product
(
id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '商品名称',
price INT(11) DEFAULT 0 COMMENT '价格',
version INT(11) DEFAULT 0 COMMENT '乐观锁版本号',
PRIMARY KEY (id)
);
INSERT INTO product (id, NAME, price) VALUES (1, '笔记本', 100);
step2:创建实体类
cpp
@Data
public class Product {
private Long id;
private String name;
private Integer price;
private Integer version;
}
step3:创建Mapper
cpp
public interface ProductMapper extends BaseMapper<Product> {
}
step4:测试
cpp
@Resource
private ProductMapper productMapper;
@Test
public void testConcurrentUpdate() {
//1、小李
Product p1 = productMapper.selectById(1L);
//2、小王
Product p2 = productMapper.selectById(1L);
//3、小李将价格加了50元,存入了数据库
p1.setPrice(p1.getPrice() + 50);
int result1 = productMapper.updateById(p1);
System.out.println("小李修改结果:" + result1);
//4、小王将商品减了30元,存入了数据库
p2.setPrice(p2.getPrice() - 30);
int result2 = productMapper.updateById(p2);
System.out.println("小王修改结果:" + result2);
//最后的结果
Product p3 = productMapper.selectById(1L);
System.out.println("最后的结果:" + p3.getPrice());
}