mybatis-plus 提供了枚举处理器,让我们可以优雅地在数据库字段和 java 枚举之间进行转换,而不需要手动处理映射关系。
一、为什么需要枚举处理器?
数据库中通常用 0/1 或 'a'/'b' 这样的值表示状态,而 java 中我们希望使用枚举类型。没有枚举处理器时,需要手动转换,容易出错且代码冗余。
二、实现方式
在枚举字段上加 @enumvalue,标记哪个字段的值存入数据库:
示例:


【备注】:
类型处理器多是由mybatis提供;
但是mybatis-plus在此基础上,添加了两个常用的类型处理器
2-1、实现步骤
1、通过注解@enumvalue,告诉mp,枚举中的哪一个字段作为数据库中的存值

2、通过配置项,让枚举处理器生效

3、对于枚举的返回值,由springmvc中的jackson json处理,通过注解@jsonvalue,标记返回枚举中的哪一个值。

2-2、小结:

三、反序列化时(接收前端参数),配合@jsoncreator
前端传来 json 数据 → java 把它转换成对象,这个过程会遇到坑!
若是枚举示例如下:

按照当前逻辑,当传值是desc字符串时:
{
"username":"商丛书6",
"email":"shang@qq.com",
"age":22,
"status":"冻结"
}
数据库存值没有问题。
但是当传值是value时:
{
"username":"商丛书7",
"email":"shang@qq.com",
"age":22,
"status":1
}存值有误:

原因:
因为 jackson 默认支持按枚举的 ordinal(下标顺序)来反序列化,而不是你 @enumvalue 定义的 code 值:
public enum userstatus {
normal(1, "正常"), // ordinal=0,code=1
frozen(-1, "冻结"); // ordinal=1,code=0
}整个链路:
postman 传 "冻结"
↓ jackson 反序列化(@jsonvalue 的 desc 字段匹配)
userstatus.normal 枚举对象
↓ mybatis-plus 写库(@enumvalue 的 value 字段)
数据库存 -1postman 传 1
↓ jackson 按 ordinal 匹配(第1个枚举)
userstatus.frozen 枚举对象
↓ mybatis-plus 写库
数据库存 -13-1、解决方法:@jsoncreator
在枚举里加 @jsoncreator 方法,根据你想支持的传值方式来写。
@jsoncreator 是加在枚举类里的一个静态方法上,这个方法你自己来写:
@getter
public enum userstatus {
normal(1, "正常"),
frozen(-1, "冻结");
@enumvalue
private int value;
@jsonvalue
private string desc;
userstatus(int value, string desc) {
this.value = value;
this.desc = desc;
}
@jsoncreator
public static userstatus of(int value){
for (userstatus e : values()){
if(value == e.value){
return e;
}
}
throw new illegalargumentexception("无效的状态值: " + value);
}
}
这样前端传 "status": 1 时,jackson 就会调用这个 of(1) 方法,按 value 字段去匹配枚举,而不是按 ordinal 顺序,避免了之前说的那个坑。
【注意】:方法名不一定叫of!!!
名字随便起,@jsoncreator 才是关键,jackson 认的是这个注解,不是方法名。
叫什么都行:
@jsoncreator
public static userstatus fromcode(int code) { ... }
@jsoncreator
public static userstatus getbycode(int code) { ... }
@jsoncreator
public static userstatus create(int code) { ... }
of 只是一个约定俗成的命名习惯,参考了 java 标准库的风格(比如 optional.of()、localdate.of() 等),看起来简洁,但并不是强制要求。
一个枚举里只能有一个 @jsoncreator 方法,因为 jackson 反序列化时只能有一个入口,多了它不知道该用哪个,会报错。
如果你想同时支持数字和字符串,就在这一个方法里做兼容处理:
@jsoncreator
public static userstatus of(object val) {
string str = val.tostring().trim();
for (userstatus e : values()) {
// 既能匹配 code(数字),也能匹配 desc(中文)
if (string.valueof(e.code).equals(str) || e.desc.equals(str)) {
return e;
}
}
throw new illegalargumentexception("无效的状态值: " + val);
}这样前端传 0 或者 "正常" 都能正确匹配。
到此这篇关于mybatisplus枚举处理器的实现的文章就介绍到这了,更多相关mybatisplus枚举处理器内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论