MyBatis-Plus 注解教程

一、核心注解

1. @TableName - 表名映射

java 复制代码
import com.baomidou.mybatisplus.annotation.TableName;

// 基本用法
@TableName("user")
public class User {
    private Long id;
    private String name;
}

// 自动驼峰转下划线
@TableName(value = "user_info", autoResultMap = true)
public class User {
    // autoResultMap: 自动构建结果映射
}

// 不映射任何表(用于通用查询)
@TableName(exist = false)
public class CommonVO {
}

2. @TableId - 主键注解

java 复制代码
import com.baomidou.mybatisplus.annotation.*;

@TableName("user")
public class User {
    // 主键类型:AUTO(自增), INPUT(手动), ASSIGN_ID(雪花算法), ASSIGN_UUID
    @TableId(type = IdType.AUTO)
    private Long id;
    
    // INPUT 模式需要手动设置ID
    @TableId(type = IdType.INPUT)
    private Long id;
    
    // 雪花算法分配ID(默认)
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    
    // UUID分配
    @TableId(type = IdType.ASSIGN_UUID)
    private String id;
    
    // 指定字段名
    @TableId(value = "user_id", type = IdType.AUTO)
    private Long id;
}

3. @TableField - 字段映射

java 复制代码
public class User {
    // 指定数据库字段名
    @TableField("user_name")
    private String name;
    
    // 不映射到数据库
    @TableField(exist = false)
    private String tempField;
    
    // 插入时填充策略
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    
    // 更新时填充策略
    @TableField(fill = FieldFill.UPDATE)
    private LocalDateTime updateTime;
    
    // 插入和更新都填充
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private String version;
    
    // 不进行条件查询的字段
    @TableField(select = false)
    private String password;
    
    // 加密字段(需要配合TypeHandler)
    @TableField(typeHandler = EncryptTypeHandler.class)
    private String phone;
    
    // 更新时忽略null值
    @TableField(updateStrategy = FieldStrategy.IGNORED)
    private String remark;
    
    // 数字比较策略
    @TableField(condition = SqlCondition.LIKE)
    private String keywords;
}

二、逻辑删除注解 @TableLogic

java 复制代码
@TableName("user")
public class User {
    @TableId
    private Long id;
    
    // 逻辑删除字段
    @TableLogic(value = "0", delval = "1")
    private Integer deleted;
    
    // 不同类型
    @TableLogic(value = "false", delval = "true")
    private Boolean isDeleted;
    
    // 字符串类型
    @TableLogic(value = "正常", delval = "已删除")
    private String status;
}

// 全局配置(application.yml)
# mybatis-plus:
#   global-config:
#     db-config:
#       logic-delete-field: deleted
#       logic-delete-value: 1
#       logic-not-delete-value: 0

三、乐观锁注解 @Version

java 复制代码
@TableName("product")
public class Product {
    @TableId
    private Long id;
    
    private String name;
    private Integer price;
    
    // 乐观锁版本号
    @Version
    private Integer version;
}

// 配置乐观锁插件
@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

// 使用示例
Product product = productMapper.selectById(1);
product.setPrice(100);
// 更新时version会自动+1,如果version不匹配则更新失败
productMapper.updateById(product);

四、填充字段注解 @TableField(fill = ...)

4.1 创建填充处理器

java 复制代码
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    
    @Override
    public void insertFill(MetaObject metaObject) {
        // 插入时自动填充
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
        this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
        this.strictInsertFill(metaObject, "createdBy", String.class, "system");
        this.setFieldValByName("version", 1, metaObject);
    }
    
    @Override
    public void updateFill(MetaObject metaObject) {
        // 更新时自动填充
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
        this.strictUpdateFill(metaObject, "updatedBy", String.class, "system");
    }
}

4.2 实体类使用

java 复制代码
public class BaseEntity {
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    
    @TableField(fill = FieldFill.INSERT)
    private String createdBy;
    
    @TableField(fill = FieldFill.UPDATE)
    private String updatedBy;
}

五、枚举处理注解 @EnumValue

java 复制代码
// 定义枚举
public enum UserStatus {
    NORMAL(1, "正常"),
    DISABLED(0, "禁用"),
    DELETED(-1, "删除");
    
    @EnumValue  // 标记存储到数据库的值
    private Integer code;
    
    @JsonValue   // JSON序列化的值
    private String desc;
    
    UserStatus(Integer code, String desc) {
        this.code = code;
        this.desc = desc;
    }
}

// 实体类使用
@TableName("user")
public class User {
    @TableId
    private Long id;
    
    private UserStatus status;  // 自动映射 code
}

六、复杂查询注解 @TableField

6.1 自定义SQL条件

java 复制代码
public class User {
    @TableField(condition = SqlCondition.EQUAL)
    private String name;  // 精确匹配
    
    @TableField(condition = SqlCondition.LIKE)
    private String email;  // 模糊匹配
    
    @TableField(condition = SqlCondition.LIKE_LEFT)
    private String code;   // 左模糊
    
    @TableField(condition = SqlCondition.LIKE_RIGHT)
    private String title;  // 右模糊
}

6.2 JSON字段映射

java 复制代码
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;

@TableName(autoResultMap = true)  // 必须开启自动映射
public class User {
    // JSON字段需要使用TypeHandler
    @TableField(typeHandler = JacksonTypeHandler.class)
    private List<String> tags;
    
    @TableField(typeHandler = JacksonTypeHandler.class)
    private Map<String, Object> config;
}

七、完整示例

java 复制代码
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;

@Data
@TableName(value = "sys_user", autoResultMap = true)
public class SysUser {
    
    @TableId(type = IdType.ASSIGN_ID)
    private Long userId;
    
    @TableField("username")
    private String username;
    
    @TableField(value = "password", select = false)
    private String password;
    
    @TableField(condition = SqlCondition.LIKE)
    private String nickname;
    
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    
    @TableLogic(value = "0", delval = "1")
    private Integer isDeleted;
    
    @Version
    private Integer version;
    
    @TableField(exist = false)
    private List<Role> roles;
    
    @TableField(typeHandler = JacksonTypeHandler.class)
    private List<String> permissions;
}

八、注解对比总结

注解 用途 常用场景
@TableName 表名映射 实体类对应不同表名
@TableId 主键配置 ID生成策略配置
@TableField 字段配置 字段映射、填充、忽略
@TableLogic 逻辑删除 软删除功能
@Version 乐观锁 并发控制
@EnumValue 枚举映射 枚举值存储

九、注意事项

  1. autoResultMap=true: 使用TypeHandler需要开启

  2. exist=false: 临时字段不参与SQL

  3. select=false: 不查询该字段(如密码)

  4. 逻辑删除: 需要配置拦截器才能自动过滤

  5. 乐观锁: 更新时必须带version字段

  6. 填充策略: 需要实现MetaObjectHandler

这套注解大大简化了MyBatis的开发工作,合理使用可以避免大量手写SQL和配置。

相关推荐
程序员三明治2 小时前
【AI】Java 调用大模型 API 实战:从 OpenAI 协议到 SiliconFlow 流式响应解析
java·开发语言·人工智能
2501_913061342 小时前
JVM虚拟机——面试中的八股文
java·jvm·面试
A-Jie-Y2 小时前
JAVA设计模式-单例模式
java·设计模式
编程之升级打怪2 小时前
设计模板引擎类的主要接口
java
ffqws_2 小时前
Spring Boot 整合 PageHelper 实现分页查询
java·spring boot·mybatis
大龄码农-涵哥2 小时前
Java调用AI大模型API入门:从零开始接入ChatGPT/通义千问
java·人工智能·chatgpt
ch.ju2 小时前
Java程序设计(第3版)第二章——for嵌套输出图形
java
XiYang-DING2 小时前
【Java EE】工厂模式
java·python·java-ee
liulilittle2 小时前
递归复制搜索所有的lua文件到指定目录
java·开发语言·lua·cmd