MyBatis-Plus 中 @TableField 注解详解
本文旨在讲解 @TableField 内部属性作用,想了解如何 java 集成 MyBatis-Plus 的同学,请移步springboot 集成 mybatis!
1 @TableField 的属性说明()
依赖版本:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.5.9</version>
</dependency>
在 @TableField 注解中,定义了一系列属性和方法,这些属性和方法用于在 MyBatis-Plus 中更细粒度地控制实体类字段与数据库表字段之间的映射关系及行为。下面我将逐一解释这些属性和方法的作用,并提供一些示例来说明它们是如何使用的。
1. value()
作用:指定数据库表中的字段名,如果未指定,则默认使用实体类中的字段名,但是,如果配置了匹配规则的话,如小驼峰(mapUnderscoreToCamelCase),则是将单词全部小写再分割开后,用下划线连接,如 userName:则匹配的数据库字段为 user_name(value 属性默认未开启匹配规则)。
例:
@TableField(value = "user_name")
private String userName;
因为 value 属性的特殊性,也可以直接写成
@TableField("user_name")
private String userName;
这里,实体类中的 userName 字段映射到数据库中的 user_name 字段。
2. exist()
作用:标记该字段在数据库表中是否存在,默认为 true。如果设置为 false,则在插入或更新操作时,会忽略这个字段。
例:
@TableField(exist = false)
private String virtualField;
这里,virtualField 在数据库表中不存在,因此在进行CRUD操作时会被忽略。
在java中也有类似作用的关键词 transient,还有注解 @Transient,使用方法如下:
//注解方式
@Transient
private String virtualField;
//关键字方式
private transient String virtualField;
这样 virtualField 字段就只存在于代码层,却不会存在于数据库。
有一点需要注意,因为字段在数据库中不存在,那么从数据库查询后获取该字段的值时,是空的,该字段需要重新 set 值
3. condition()
作用:指定 SQL 条件表达式,用于在 WHERE 语句中动态添加条件。
例:
@TableField(condition = "del_flag = 0")
private Integer del_flag;
在查询时,会自动在WHERE子句中添加 del_flag = 0 的条件。
说明一下,这个属性不常用,也建议大家慎用,主要原因在这个属性会添加默认过滤属性,像作者添加的 del_flag 字段确实可能会用上这个 condition 属性,但是如果存在查询 del_flag = 1 的条件时,这个属性便会起副作用,导致过滤会变成 where del_flag = 0 and del_flag = 1,这样就会使过滤出现冲突问题,从而导致 sql 出现失效问题。
4. update()
作用:指定 SQL 的 SET 语句中的条件表达式,用于动态更新操作。
例:
@TableField(update = "update_time = #{now}, status = 1")
private Date updateTime;
在更新时,除了更新 update_time 为当前时间外,还会将 status 更新为 1。
5. insertStrategy(), updateStrategy(), whereStrategy()
作用:分别控制字段在插入、更新和WHERE查询时的策略。FieldStrategy 枚举值包括 IGNORED(忽略)、NOT_NULL(非空判断)、NOT_EMPTY(非空且非空字符串判断)、DEFAULT(默认,跟随全局配置)。
例:
@TableField(insertStrategy = FieldStrategy.NOT_NULL)
private String remark;
在插入时,如果 remark 为 null,则不会插入这个字段。
6. fill()
作用:指定字段的自动填充策略。FieldFill 枚举值包括 DEFAULT(不自动填充)、INSERT(插入时自动填充)、UPDATE(更新时自动填充)等。
例:
@TableField(fill = FieldFill.INSERT)
private Date createTime;
在插入时,会自动填充 create_time 字段。
7. select()
作用:标记该字段是否参与查询,默认为true。如果设置为false,则在查询时忽略这个字段。
例:
@TableField(select = false)
private String password;
在查询时,不会包含 password 字段。
8. keepGlobalFormat()
作用:是否保持全局的格式化,比如 %s 等占位符的格式化,默认为 false。
较少直接用于字段注解,更多是在全局配置中考虑,在此就不举例说明了。
9. jdbcType()
作用:指定字段在数据库中的JDBC类型。
例:
@TableField(jdbcType = JdbcType.VARCHAR)
private String name;
指定 name 字段的 JDBC 类型为 VARCHAR。
10. typeHandler()
作用:指定该字段的类型处理器,用于自定义字段的Java类型与数据库类型的转换。
例:
@TableField(typeHandler = MyCustomTypeHandler.class)
private MyCustomType myCustomType;
使用自定义的 MyCustomTypeHandler 来处理 myCustomType 字段的转换。
说明一下,该属性用于将 java 的对象存储在一个字段上,建议数据库字段类型为 json 最好,java 中的属性类型可以为 Object
,也可以为 List 或者 Map 类型,Object即可以为基础数据类型,也可以为自定义对象类。想了解的也可以移步使用 mybatis 中的自定义 TypeHandler 处理 PostgreSQL 中的 Json 类型,该属性使用其实比较简单,如果想自定义处理器的话,会稍微复杂点。
11. numericScale()
作用:指定数值类型的精度(小数位数),在某些数据库中可能需要精确控制数值的精度。
例:
@TableField(numericScale = "2")
private BigDecimal price;
指定 price 字段的精度为 2 位小数。
2 实体类的一些感悟(非本文重点,可以跳过)
日常开发过程中,其实定义好一个是实体字段,其实非常重要,因为我们的代码,也无非是基于这个实体字段的判断与修改,以下是作者在日常开发中针对实体类的一些理解与感悟,与文章上半部分联系不大,大家可以选择性阅读。
1. 类的部分
- @Data 注解,非常实用的类注解,这里不再赘述其作用,有兴趣的读者可以百度~
- @NoArgsConstructor 注解,需要 new 去创建对象,一个注解帮你搞定空参构造函数。
- 自定义基类(基类可以定义实体类都需要的属性,如 id、createBy、createTime、updateBy、updateTime 等等),然后实体再通过继承基类,获得基类的所有属性。
2. 属性的部分
- 日期类型属性要区分是 Date(yyyy-MM-dd HH:mm:ss)类型,还是 LocalDate(yyyy-MM-dd)
- 日期类型属性的注解:@Temporal 注解 与 @JsonFormat 注解会在日期类型数据入库与查询时将日期数据解析成正确的日期格式
@Temporal(TemporalType.DATE)
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate date1;
@Temporal(TemporalType.TIMESTAMP)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date date2;
- 需要初始化的值是固定的,比如 del_flag,这样在创建数据时,则不需要对 del_flag 再次赋值,他会在创建时给默认值 0
private Integer del_flag = 0;
暂时就想到这么多,后面看情况再补充~