05.类型增强
类型增强
字段类型处理器
类型处理器,用于 JavaType 与 JdbcType 之间的转换,用于 PreparedStatement 设置参数值和从 ResultSet 或 CallableStatement 中取出一个值。
@Data
@Accessors(chain = true)
@TableName(autoResultMap = true)
public class User {
private Long id;
...
/**
* 注意!! 必须开启映射注解
*
* @TableName(autoResultMap = true)
*
* 以下两种类型处理器,二选一 也可以同时存在
*
* 注意!!选择对应的 JSON 处理器也必须存在对应 JSON 解析依赖包
*/
@TableField(typeHandler = JacksonTypeHandler.class)
// @TableField(typeHandler = FastjsonTypeHandler.class)
private OtherInfo otherInfo;
}
该注解对应了 XML 中写法为:
<result column="other_info" jdbcType="VARCHAR" property="otherInfo" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />
案例
首先,自定义类型处理器:
public class TestTypeHandler extends BaseTypeHandler<String> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, "TestTypeHandler set {" + parameter + "}");
}
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
String string = rs.getString(columnName);
return "TestTypeHandler(rs columnName) get {" + string + "}";
}
@Override
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String string = rs.getString(columnIndex);
return "TestTypeHandler(rs columnIndex) get {" + string + "}";
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String string = cs.getString(columnIndex);
return "TestTypeHandler(cs columnIndex) get {" + string + "}";
}
}
然后在需要使用该类型的地方添加注解:
@TableField(typeHandler = TestTypeHandler.class)
private String email;
主键
自 3.3.0 开始,默认使用雪花算法+UUID(不含中划线):
方法 | 主键生成策略 | 主键类型 | 说明 |
---|---|---|---|
nextId | ASSIGN_ID,ID_WORKER,ID_WORKER_STR | Long,Integer,String | 支持自动转换为 String 类型,但数值类型不支持自动转换,需精准匹配,例如返回 Long,实体主键就不支持定义为 Integer |
nextUUID | ASSIGN_UUID,UUID | String | 默认不含中划线的 UUID 生成 |
- 方式一:声明为 Bean 供 Spring 扫描注入
@Component
public class CustomIdGenerator implements IdentifierGenerator {
@Override
public Long nextId(Object entity) {
//可以将当前传入的class全类名来作为bizKey,或者提取参数来生成bizKey进行分布式Id调用生成.
String bizKey = entity.getClass().getName();
//根据bizKey调用分布式ID生成
long id = ....;
//返回生成的id值即可.
return id;
}
}
- 方式二:使用配置类
@Bean
public IdentifierGenerator idGenerator() {
return new CustomIdGenerator();
}
- 方式三:通过 MybatisPlusPropertiesCustomizer 自定义
@Bean
public MybatisPlusPropertiesCustomizer plusPropertiesCustomizer() {
return plusProperties -> plusProperties.getGlobalConfig().setIdentifierGenerator(new CustomIdGenerator());
}
通用枚举
自 3.1.0 开始,如果你无需使用原生枚举,可配置默认枚举来省略扫描通用枚举配置默认枚举配置。
声明通用枚举属性
// 方式一:使用 @EnumValue 注解枚举属性
public enum GradeEnum {
PRIMARY(1, "小学"), SECONDORY(2, "中学"), HIGH(3, "高中");
GradeEnum(int code, String descp) {
this.code = code;
this.descp = descp;
}
@EnumValue//标记数据库存的值是code
private final int code;
//。。。
}
// 方式二:枚举属性,实现 IEnum 接口如下:
public enum AgeEnum implements IEnum<Integer> {
ONE(1, "一岁"),
TWO(2, "二岁"),
THREE(3, "三岁");
private int value;
private String desc;
@Override
public Integer getValue() {
return this.value;
}
}
// 实体属性使用枚举类型
public class User {
/**
* 名字
* 数据库字段: name varchar(20)
*/
private String name;
/**
* 年龄,IEnum接口的枚举处理
* 数据库字段:age INT(3)
*/
private AgeEnum age;
/**
* 年级,原生枚举(带{@link com.baomidou.mybatisplus.annotation.EnumValue}):
* 数据库字段:grade INT(2)
*/
private GradeEnum grade;
}
配置扫描通用枚举
mybatis-plus:
# 支持统配符 * 或者 ; 分割
typeEnumsPackage: com.baomidou.springboot.entity.enums
....
- Jackson
// 重写toString方法
@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer(){
return builder -> builder.featuresToEnable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
}
// 注解处理
public enum GradeEnum {
PRIMARY(1, "小学"), SECONDORY(2, "中学"), HIGH(3, "高中");
GradeEnum(int code, String descp) {
this.code = code;
this.descp = descp;
}
@EnumValue
@JsonValue //标记响应json值
private final int code;
}
- Fastjson
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(SerializerFeature.WriteEnumUsingToString);
@JSONField(serialzeFeatures= SerializerFeature.WriteEnumUsingToString)
private UserStatus status;