注解配置
本文详细介绍了 MyBatisPlus 注解的用法及属性,提供了源码链接以便深入理解。欢迎通过下方链接查看注解类的源码。
@TableName
该注解用于指定实体类对应的数据库表名。当实体类名与数据库表名不一致,或者实体类名不是数据库表名的驼峰写法时,您需要使用这个注解来明确指定表名。
@TableName("sys_user")public class User { private Long id; private String name; private Integer age; private String email;}
value
类型:
String
默认值:
""
指定实体类对应的数据库表名。如果实体类名与表名不一致,使用这个属性来指定正确的表名。
schema
类型:
String
默认值:
""
指定数据库的 Schema 名称。通常情况下,如果你的数据库没有使用 Schema 来组织表,这个属性可以不填写。
keepGlobalPrefix
类型:
boolean
默认值:
false
当全局配置了 tablePrefix 时,这个属性决定是否保持使用全局的表前缀。如果设置为 true,即使注解中指定了表名,也会自动加上全局的表前缀。
resultMap
类型:
String
默认值:
""
指定在 XML 中定义的 ResultMap 的 ID,用于将查询结果映射到特定类型的实体类对象。
autoResultMap
类型:
boolean
默认值:
false
是否自动构建 resultMap。如果已经设置了 resultMap,这个属性不会生效。
excludeProperty
类型:
String[]
默认值:
{}
添加于:
@since 3.3.1
指定在映射时需要排除的属性名。这些属性将不会被包含在生成的 SQL 语句中。
@TableId
该注解用于标记实体类中的主键字段。如果你的主键字段名为 id,你可以省略这个注解。
@TableName("sys_user")public class User { @TableId private Long id; private String name; private Integer age; private String email;}
value
类型:
String
默认值:
""
指定数据库表的主键字段名。如果不设置,MyBatis-Plus 将使用实体类中的字段名作为数据库表的主键字段名。
类型:
Enum
默认值:
IdType.NONE
指定主键的生成策略。
IdType 枚举类型定义
IdType.AUTO
:使用数据库自增 ID 作为主键。
IdType.NONE
:无特定生成策略,如果全局配置中有 IdType 相关的配置,则会跟随全局配置。
IdType.INPUT
:在插入数据前,由用户自行设置主键值。
IdType.ASSIGN_ID
:自动分配
ID
,适用于
Long
、
Integer
、
String
类型的主键。默认使用雪花算法通过
IdentifierGenerator
的
nextId
实现。
@since 3.3.0
IdType.ASSIGN_UUID
:自动分配
UUID
,适用于
String
类型的主键。默认实现为
IdentifierGenerator
的
nextUUID
方法。
@since 3.3.0
@TableField
该注解用于标记实体类中的非主键字段,它告诉 MyBatis-Plus 如何映射实体类字段到数据库表字段。如果你的实体类字段名遵循驼峰命名规则,并且与数据库表字段名一致,你可以省略这个注解。
@TableName("sys_user")public class User { @TableId private Long id; @TableField("nickname") // 映射到数据库字段 "nickname" private String name; private Integer age; private String email;}
value
类型:
String
默认值:
""
指定数据库中的字段名。如果你的实体类字段名与数据库字段名不同,使用这个属性来指定正确的数据库字段名。
exist
类型:
boolean
默认值:
true
指示这个字段是否存在于数据库表中。如果设置为 false,MyBatis-Plus 在生成 SQL 时会忽略这个字段。
condition
类型:
String
默认值:
""
在执行实体查询(EntityQuery)时,指定字段的条件表达式。这允许你自定义字段在 WHERE 子句中的比较方式。如果该项有值则按设置的值为准,无值则默认为全局的
%s=#{%s}
为准。
写法详见 SqlCondition 。
假设我们有一个实体类 User,它有 id、name 和 age 三个字段。我们想要查询所有年龄大于 18 岁的用户,我们可以使用 QueryWrapper 来构建这个查询,直接传递 User 实体类实例:
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.baomidou.mybatisplus.annotation.TableField;import com.baomidou.mybatisplus.annotation.SqlCondition;
// 实体类定义@TableName("sys_user")public class User { @TableId private Long id;
private String name;
@TableField(condition = "%s > #{%s}") // 自定义 age 字段的条件表达式 private Integer age;
private String email;}
// 使用 EntityQuery 构建查询public List<User> findUserAgeOver18() { // 创建 User 实例,用于设置查询条件 User queryEntity = new User(); queryEntity.setAge(18); // 设置 age 字段的值
// 创建 QueryWrapper 实例,并传递 User 实例 QueryWrapper<User> queryWrapper = new QueryWrapper<>(queryEntity);
// 执行查询 List<User> userList = userMapper.selectList(queryWrapper);
return userList;}
在这个例子中,我们通过
@TableField(condition = "%s > #{%s}")
注解为 age 字段设置了自定义的条件表达式。当构建查询时,我们创建了一个 User 实例,并设置了 age 字段的值为 18。然后,我们使用这个实例来创建 QueryWrapper,MyBatis-Plus 会根据实体类上的注解自动生成相应的 SQL 查询条件。
执行 findUserAgeOver18 方法时,MyBatis-Plus 会生成类似以下的 SQL 语句:
SELECT * FROM sys_user WHERE age > 18;
通过这种方式,condition 属性允许我们自定义字段在查询时的行为,使得查询更加灵活和符合特定需求,同时避免了手动编写 SQL 片段的繁琐。
update
类型:
String
默认值:
""
在执行更新操作时,指定字段在 SET 子句中的表达式。这个属性的优先级高于 el 属性,允许你自定义字段的更新逻辑。
假设我们有一个实体类 User,其中包含一个 version 字段,我们希望在每次更新用户信息时,自动将 version 字段的值增加 1。我们可以使用 @TableField 注解的 update 属性来实现这个功能:
import com.baomidou.mybatisplus.annotation.TableField;
@TableName("sys_user")public class User { @TableId private Long id;
private String name;
private Integer age;
private String email;
@TableField(update="
%s+1") // 自定义更新时的表达式 private Integer version;}
在这个例子中,
@TableField(update="%s+1")
注解告诉 MyBatis-Plus,在执行更新操作时,对于 version 字段,应该使用
version = version + 1
的表达式。这意味着,每次更新用户信息时,version 字段的值都会自动增加 1。
如果我们执行以下更新操作:
User user = new User();user.setId(1L);user.setName("Updated Name");user.setAge(30);
userMapper.updateById(user);
MyBatis-Plus 会自动生成类似以下的 SQL 语句:
UPDATE sys_userWHERE id = 1;
通过这种方式,update 属性允许我们自定义字段在更新时的行为,使得更新操作更加灵活和符合特定需求,同时避免了手动编写 SQL 片段的繁琐。
insertStrategy
类型:
Enum
默认值:
FieldStrategy.DEFAULT
定义在插入新记录时,如何处理字段的值。这个属性允许你控制字段是否应该包含在 INSERT 语句中,以及在什么条件下包含。
FieldStrategy 枚举类型定义
假设我们有一个实体类 User,其中包含一个 nickname 字段,我们希望在插入新用户时,只有当 nickname 不为空时才插入该字段。我们可以使用 @TableField 注解的 insertStrategy 属性来实现这个功能:
import com.baomidou.mybatisplus.annotation.TableField;import com.baomidou.mybatisplus.annotation.FieldStrategy;
@TableName("sys_user")public class User { @TableId private Long id;
@TableField(insertStrategy = FieldStrategy.NOT_EMPTY) // 仅在 nickname 不为空时插入 private String nickname;
private Integer age;
private String email;}
在这个例子中,
@TableField(insertStrategy = FieldStrategy.NOT_EMPTY)
注解告诉 MyBatis-Plus,在插入新用户时,只有当 nickname 字段不为空时才将其包含在 INSERT 语句中。
如果我们执行以下插入操作:
User user = new User();user.setNickname("John Doe");user.setAge(25);
userMapper.insert(user);
MyBatis-Plus 会自动生成类似以下的 SQL 语句:
INSERT INTO sys_user (nickname, age, email)
如果 nickname 字段为空,生成的 SQL 将不包含 nickname 字段:
INSERT INTO sys_user (age, email)
其效果等同于如下 MyBatis 的自定义 XML 配置:
<mapper namespace="com.example.mapper.UserMapper">
<!-- 插入用户 --> <insert id="insertUser" parameterType="com.example.entity.User"> INSERT INTO sys_user ( <if test="nickname != null and nickname != ''"> nickname, </if> age, email ) VALUES ( <if test="nickname != null and nickname != ''"> #{nickname}, </if> #{age}, #{email} ) </insert>
</mapper>
通过这种方式,insertStrategy 属性允许我们自定义字段在插入时的行为,使得插入操作更加灵活和符合特定需求,同时避免了手动编写 SQL 片段的繁琐。
updateStrategy
类型:
Enum
默认值:
FieldStrategy.DEFAULT
定义在更新记录时,如何处理字段的值。这个属性允许你控制字段是否应该包含在 UPDATE 语句的 SET 子句中,以及在什么条件下包含。
参见 insertStrategy 属性以获取更多关于 FieldStrategy 枚举类型的详细信息。
假设我们有一个实体类 User,其中包含一个 nickname 字段,我们希望在更新用户信息时,总是更新 nickname 字段,无论其值是否为空。我们可以使用 @TableField 注解的 updateStrategy 属性来实现这个功能:
import com.baomidou.mybatisplus.annotation.TableField;import com.baomidou.mybatisplus.annotation.FieldStrategy;
@TableName("sys_user")public class User { @TableId private Long id;
@TableField(updateStrategy = FieldStrategy.ALWAYS) // 总是更新 nickname,忽略值的检查 private String nickname;
private Integer age;
private String email;}
在这个例子中,
@TableField(updateStrategy = FieldStrategy.ALWAYS)
注解告诉 MyBatis-Plus,在更新用户信息时,总是将 nickname 字段包含在 UPDATE 语句的 SET 子句中,忽略其值的检查。
如果我们执行以下更新操作:
User user = new User();user.setId(1L);user.setNickname("Updated Nickname");user.setAge(30);
userMapper.updateById(user);
MyBatis-Plus 会自动生成类似以下的 SQL 语句:
UPDATE sys_userWHERE id = 1;
无论 nickname 字段的值是否为空,生成的 SQL 都会包含 nickname 字段。也就是说,即使 nickname 字段的值为空,生成的 SQL 也会更新 nickname 字段为 NULL。
通过这种方式,updateStrategy 属性允许我们自定义字段在更新时的行为,使得更新操作更加灵活和符合特定需求,同时避免了手动编写 SQL 片段的繁琐。
whereStrategy
类型:
Enum
默认值:
FieldStrategy.DEFAULT
定义在生成更新语句的 WHERE 子句时,如何处理字段的值。这个属性允许你控制字段是否应该包含在 WHERE 子句中,以及在什么条件下包含。
参见 insertStrategy 和 updateStrategy 属性以获取更多关于 FieldStrategy 枚举类型的详细信息。
假设我们有一个实体类 User,其中包含一个 nickname 字段,我们希望在更新用户信息时,只有当 nickname 字段不为空时,才将其作为 WHERE 子句的条件。我们可以使用 @TableField 注解的 whereStrategy 属性来实现这个功能:
import com.baomidou.mybatisplus.annotation.TableField;import com.baomidou.mybatisplus.annotation.FieldStrategy;
@TableName("sys_user")public class User { @TableId private Long id;
@TableField(whereStrategy = FieldStrategy.NOT_EMPTY) // 仅在 nickname 不为空时作为 WHERE 条件 private String nickname;
private Integer age;
private String email;}
在这个例子中,
@TableField(whereStrategy = FieldStrategy.NOT_EMPTY)
注解告诉 MyBatis-Plus,在使用 whereEntity 生成更新语句的 WHERE 子句时,只有当 nickname 字段不为空时,才将其包含在 WHERE 子句中。
如果我们执行以下更新操作:
User user = new User();
User whereEntity = new User();whereEntity.setNickname("John Doe");whereEntity.setAge(30);
// 使用 whereEntity 方法UpdateWrapper<User> updateWrapper = new UpdateWrapper<>(whereEntity);userMapper.update(user, updateWrapper);
MyBatis-Plus 会自动生成类似以下的 SQL 语句:
UPDATE sys_userWHERE nickname = 'John Doe' AND age = 30;
如果 nickname 字段为空,生成的 SQL 将不包含 nickname 字段:
UPDATE sys_userWHERE age = 30;
其效果等同于如下 MyBatis 的自定义 XML 配置:
<mapper namespace="com.example.mapper.UserMapper">
<!-- 更新用户信息 --> <update id="updateUser" parameterType="com.example.entity.User"> UPDATE sys_user SET email = #{email} <where> <if test="nickname != null and nickname != ''"> AND nickname = #{nickname} </if> AND age = #{age} </where> </update>
</
mapper>
通过这种方式,whereStrategy 属性允许我们自定义字段在 WHERE 子句中的行为,使得更新操作更加灵活和符合特定需求,同时避免了手动编写 SQL 片段的繁琐。参见 insertStrategy 和 updateStrategy 属性以获取更多关于 FieldStrategy 枚举类型的详细信息。
类型:
Enum
默认值:
FieldFill.DEFAULT
字段自动填充策略。该属性用于指定在执行数据库操作(如插入、更新)时,如何自动填充字段的值。通过使用 FieldFill 枚举,可以灵活地控制字段的填充行为。
FieldFill 枚举类型定义
FieldFill.DEFAULT
:默认不进行填充,依赖于数据库的默认值或手动设置。
FieldFill.INSERT
:在插入操作时自动填充字段值。
FieldFill.UPDATE
:在更新操作时自动填充字段值。
FieldFill.INSERT_UPDATE
:在插入和更新操作时都会自动填充字段值。
假设有一个 User 实体类,其中包含 createTime 和 updateTime 字段,我们希望在创建用户时自动填充创建时间,在更新用户信息时自动填充更新时间。
import com.baomidou.mybatisplus.annotation.FieldFill;import com.baomidou.mybatisplus.annotation.TableField;import com.baomidou.mybatisplus.annotation.TableName;import java.time.LocalDateTime;
@TableName("user")public class User { // 其他字段...
@TableField(fill = FieldFill.INSERT) private LocalDateTime createTime;
@TableField(fill = FieldFill.UPDATE) private LocalDateTime updateTime;
// 构造函数、getter 和 setter...}
在这个示例中,createTime 字段会在插入操作时自动填充当前时间,而 updateTime 字段会在更新操作时自动填充当前时间。这样,我们就不需要在每次数据库操作时手动设置这些时间字段的值了。
请注意 ,为了使自动填充功能正常工作,您需要在 MyBatis-Plus 的配置中设置相应的自动填充处理器,并且确保在实体类对应的 Mapper 接口中定义了相应的插入和更新方法。
select
类型:
boolean
默认值:
true
指示在执行查询操作时,该字段是否应该包含在 SELECT 语句中。这个属性允许您控制查询结果中包含哪些字段,从而提供更细粒度的数据访问控制。
当 select 属性设置为 true(默认值)时,该字段将包含在查询结果中。
当 select 属性设置为 false 时,即使该字段存在于数据库表中,它也不会包含在查询结果中。这在需要保护敏感数据或优化查询性能时非常有用。
假设有一个 User 实体类,其中包含 password 字段,我们希望在查询用户信息时排除密码字段,以保护用户隐私。
import com.baomidou.mybatisplus.annotation.TableField;import com.baomidou.mybatisplus.annotation.TableName;
@TableName("user")public class User { // 其他字段...
@TableField(select = false) private String password;
// 构造函数、getter 和 setter...}
在这个示例中,当执行查询操作时,password 字段不会被包含在 SELECT 语句中,因此不会出现在查询结果中。这样,即使数据库中存储了密码信息,也不会在常规查询中泄露。
请注意,@TableField 注解的 select 属性仅影响 MyBatis-Plus 生成的查询语句,不会影响其他框架或手动编写的 SQL 语句。此外,如果使用了 select = false 的字段,那么在自定义查询或使用其他方式访问该字段时,需要特别注意数据的安全性和完整性。
keepGlobalFormat
类型:
boolean
默认值:
false
指示在处理字段时是否保持使用全局 DbConfig 中定义的 columnFormat 规则。这个属性用于控制字段值在数据库操作中是否应用全局的列格式化规则。
jdbcType
类型:
JdbcType
默认值:
JdbcType.UNDEFINED
JDBC类型,用于指定字段在数据库中的数据类型。这个属性允许您显式地设置字段的数据库类型,以确保与数据库的兼容性,特别是在处理特殊类型或自定义类型时。
当 jdbcType 属性设置为 JdbcType.UNDEFINED(默认值)时,MyBatis-Plus 将根据字段的 Java 类型自动推断其 JDBC 类型。
当 jdbcType 属性设置为特定的 JdbcType 枚举值时,该字段将使用指定的 JDBC 类型进行数据库操作。这可以用于解决类型映射问题,或者在需要精确控制数据库类型时使用。
假设有一个 CustomType 实体类,其中包含一个自定义类型 MyCustomType 的字段,我们希望在数据库中以特定的 JDBC 类型存储。
import com.baomidou.mybatisplus.annotation.TableField;import com.baomidou.mybatisplus.annotation.TableName;import org.apache.ibatis.type.JdbcType;
@TableName("custom_type")public class CustomType { // 其他字段...
@
TableField(value = "my_custom_field", jdbcType = JdbcType.VARCHAR) private MyCustomType myCustomField;
// 构造函数、getter 和 setter...}
在这个示例中,myCustomField 字段将使用 VARCHAR JDBC 类型进行数据库操作。这样,即使 MyCustomType 是一个自定义类型,它也会被转换为 VARCHAR 类型存储在数据库中。
请注意 ,jdbcType 属性仅在特定情况下需要设置,例如当 Java 类型与数据库类型之间存在不明确的映射关系时。在大多数情况下,MyBatis-Plus 能够自动处理类型映射,因此不需要显式设置 jdbcType。此外,jdbcType 属性仅影响 MyBatis-Plus 生成的 SQL 语句,不会影响其他框架或手动编写的 SQL 语句。
typeHandler
类型:
Class<? extends TypeHandler>
默认值:
UnknownTypeHandler.class
类型处理器,用于指定在数据库操作中如何处理特定字段的值。这个属性允许您自定义字段值的转换逻辑,以适应特定的数据类型或业务需求。
当 typeHandler 属性未设置(即使用默认值 UnknownTypeHandler.class)时,MyBatis-Plus 将使用默认的类型处理器来处理字段值。
当 typeHandler 属性设置为特定的 TypeHandler 子类时,该字段将使用指定的类型处理器进行数据库操作。这可以用于处理自定义类型、特殊数据格式或非标准的数据库类型。
假设我们有一个 User 实体类,其中包含一个 birthDate 字段,我们希望使用自定义的类型处理器来处理日期格式,该处理器能够将日期按照特定的格式存储在数据库中。
import com.baomidou.mybatisplus.annotation.TableField;import com.baomidou.mybatisplus.annotation.TableName;import com.example.myproject.typehandler.CustomDateTypeHandler;import java.time.LocalDate;
@TableName("user")public class User { // 其他字段...
@TableField(value = "birth_date", typeHandler = CustomDateTypeHandler.class) private LocalDate birthDate;
// 构造函数、getter 和 setter...}
在这个示例中,birthDate 字段将使用 CustomDateTypeHandler 类型处理器进行数据库操作。这样,无论是在查询时将数据库中的日期值转换为 LocalDate 对象,还是在更新时将 LocalDate 对象的日期值转换为数据库中的特定日期格式,都会使用 CustomDateTypeHandler 来处理。
CustomDateTypeHandler 可能实现如下:
import org.apache.ibatis.type.BaseTypeHandler;import org.apache.ibatis.type.JdbcType;import java.sql.CallableStatement;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.time.LocalDate;import java.time.format.DateTimeFormatter;
public class CustomDateTypeHandler extends BaseTypeHandler<LocalDate> { private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
@Override public void setNonNullParameter(PreparedStatement ps, int i, LocalDate parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter.format(FORMATTER)); }
@Override public LocalDate getNullableResult(ResultSet rs, String columnName) throws SQLException { String dateString = rs.getString(columnName); return (dateString != null) ? LocalDate.parse(dateString, FORMATTER) : null; }
// 实现其他必要的方法...}
在这个自定义类型处理器中,我们定义了一个 DateTimeFormatter 来指定日期的格式,并在 setNonNullParameter 和 getNullableResult 方法中实现了日期值的转换逻辑。
请注意 ,为了使自定义类型处理器生效,您需要确保它在 MyBatis-Plus 的配置中被正确注册,并且能够在运行时被加载。此外,自定义类型处理器的使用应当谨慎,确保其正确性和性能。更多详细信息,请参考 字段类型处理器 的内容。
numericScale
类型:
String
默认值:
""
指定小数点后保留的位数,该属性仅在执行 update 操作时生效。它用于控制数值类型字段在更新时的小数精度。
import com.baomidou.mybatisplus.annotation.TableField;import com.baomidou.mybatisplus.annotation.TableName;
@TableName("product")public class Product { // 其他字段...
@TableField(value = "price", numericScale = "2") private BigDecimal price;
// 构造函数、getter 和 setter...}
在这个示例中,price 字段在执行 update 操作时将确保小数点后保留两位。这意味着在更新价格时,无论传入的价格值小数位数是多少,都会被格式化为两位小数。
请注意 ,为了使 numericScale 属性生效,您需要确保数据库支持指定的小数位数,并且在执行 update 操作时,传入的数值类型字段值会被正确处理。此外,numericScale 属性仅影响 MyBatis-Plus 生成的 SQL 语句,不会影响其他框架或手动编写的 SQL 语句。