MyBatisPlus枚舉處理器的實(shí)現(xiàn)
MyBatis-Plus 提供了枚舉處理器,讓我們可以優(yōu)雅地在數(shù)據(jù)庫(kù)字段和 Java 枚舉之間進(jìn)行轉(zhuǎn)換,而不需要手動(dòng)處理映射關(guān)系。
一、為什么需要枚舉處理器?
數(shù)據(jù)庫(kù)中通常用 0/1 或 'A'/'B' 這樣的值表示狀態(tài),而 Java 中我們希望使用枚舉類型。沒有枚舉處理器時(shí),需要手動(dòng)轉(zhuǎn)換,容易出錯(cuò)且代碼冗余。
二、實(shí)現(xiàn)方式
在枚舉字段上加 @EnumValue,標(biāo)記哪個(gè)字段的值存入數(shù)據(jù)庫(kù):
示例:


【備注】:
類型處理器多是由mybatis提供;
但是mybatis-plus在此基礎(chǔ)上,添加了兩個(gè)常用的類型處理器
2-1、實(shí)現(xiàn)步驟
1、通過注解@EnumValue,告訴mp,枚舉中的哪一個(gè)字段作為數(shù)據(jù)庫(kù)中的存值

2、通過配置項(xiàng),讓枚舉處理器生效

3、對(duì)于枚舉的返回值,由springMVC中的Jackson json處理,通過注解@JsonValue,標(biāo)記返回枚舉中的哪一個(gè)值。

2-2、小結(jié):

三、反序列化時(shí)(接收前端參數(shù)),配合@JsonCreator
前端傳來 JSON 數(shù)據(jù) → Java 把它轉(zhuǎn)換成對(duì)象,這個(gè)過程會(huì)遇到坑!
若是枚舉示例如下:

按照當(dāng)前邏輯,當(dāng)傳值是desc字符串時(shí):
{
"username":"商叢書6",
"email":"shang@qq.com",
"age":22,
"status":"凍結(jié)"
}
數(shù)據(jù)庫(kù)存值沒有問題。
但是當(dāng)傳值是value時(shí):
{
"username":"商叢書7",
"email":"shang@qq.com",
"age":22,
"status":1
}存值有誤:

原因:
因?yàn)?Jackson 默認(rèn)支持按枚舉的 ordinal(下標(biāo)順序)來反序列化,而不是你 @EnumValue 定義的 code 值:
public enum UserStatus {
NORMAL(1, "正常"), // ordinal=0,code=1
FROZEN(-1, "凍結(jié)"); // ordinal=1,code=0
}整個(gè)鏈路:
Postman 傳 "凍結(jié)"
↓ Jackson 反序列化(@JsonValue 的 desc 字段匹配)
UserStatus.NORMAL 枚舉對(duì)象
↓ MyBatis-Plus 寫庫(kù)(@EnumValue 的 value 字段)
數(shù)據(jù)庫(kù)存 -1Postman 傳 1
↓ Jackson 按 ordinal 匹配(第1個(gè)枚舉)
UserStatus.FROZEN 枚舉對(duì)象
↓ MyBatis-Plus 寫庫(kù)
數(shù)據(jù)庫(kù)存 -13-1、解決方法:@JsonCreator
在枚舉里加 @JsonCreator 方法,根據(jù)你想支持的傳值方式來寫。
@JsonCreator 是加在枚舉類里的一個(gè)靜態(tài)方法上,這個(gè)方法你自己來寫:
@Getter
public enum UserStatus {
NORMAL(1, "正常"),
FROZEN(-1, "凍結(jié)");
@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("無效的狀態(tài)值: " + value);
}
}
這樣前端傳 "status": 1 時(shí),Jackson 就會(huì)調(diào)用這個(gè) of(1) 方法,按 value 字段去匹配枚舉,而不是按 ordinal 順序,避免了之前說的那個(gè)坑。
【注意】:方法名不一定叫of?。?!
名字隨便起,@JsonCreator 才是關(guān)鍵,Jackson 認(rèn)的是這個(gè)注解,不是方法名。
叫什么都行:
@JsonCreator
public static UserStatus fromCode(int code) { ... }
@JsonCreator
public static UserStatus getByCode(int code) { ... }
@JsonCreator
public static UserStatus create(int code) { ... }
of 只是一個(gè)約定俗成的命名習(xí)慣,參考了 Java 標(biāo)準(zhǔn)庫(kù)的風(fēng)格(比如 Optional.of()、LocalDate.of() 等),看起來簡(jiǎn)潔,但并不是強(qiáng)制要求。
一個(gè)枚舉里只能有一個(gè) @JsonCreator 方法,因?yàn)?Jackson 反序列化時(shí)只能有一個(gè)入口,多了它不知道該用哪個(gè),會(huì)報(bào)錯(cuò)。
如果你想同時(shí)支持?jǐn)?shù)字和字符串,就在這一個(gè)方法里做兼容處理:
@JsonCreator
public static UserStatus of(Object val) {
String str = val.toString().trim();
for (UserStatus e : values()) {
// 既能匹配 code(數(shù)字),也能匹配 desc(中文)
if (String.valueOf(e.code).equals(str) || e.desc.equals(str)) {
return e;
}
}
throw new IllegalArgumentException("無效的狀態(tài)值: " + val);
}這樣前端傳 0 或者 "正常" 都能正確匹配。
到此這篇關(guān)于MyBatisPlus枚舉處理器的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)MyBatisPlus枚舉處理器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之寵物醫(yī)院與商城一體的系統(tǒng)的實(shí)現(xiàn)
這是一個(gè)使用了java+Springboot+Jsp+maven+Mysql開發(fā)的寵物醫(yī)院與商城一體的系統(tǒng),是一個(gè)畢業(yè)設(shè)計(jì)的實(shí)戰(zhàn)練習(xí),具有寵物醫(yī)院和寵物商城該有的所有功能,感興趣的朋友快來看看吧2022-02-02
SpringMVC配置javaConfig及StringHttpMessageConverter示例
這篇文章主要介紹了SpringMVC配置javaConfig及StringHttpMessageConverter實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
Java實(shí)現(xiàn)經(jīng)典游戲打磚塊游戲的示例代碼
這篇文章主要介紹了如何利用Java實(shí)現(xiàn)經(jīng)典的游戲—打磚塊。玩家操作一根螢?zāi)簧纤降摹鞍糇印?,讓一顆不斷彈來彈去的“球”在撞擊作為過關(guān)目標(biāo)消去的“磚塊”的途中不會(huì)落到螢?zāi)坏紫?。感興趣的小伙伴可以了解一下2022-02-02
解讀@SpringBootApplication注解有什么用
@SpringBootApplication是SpringBoot的核心注解,主要包含@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan三個(gè)注解,這些注解共同簡(jiǎn)化了Spring應(yīng)用的配置工作,并使得通過主程序類就可以啟動(dòng)SpringBoot應(yīng)用2024-09-09
mybatis動(dòng)態(tài)插入list傳入List參數(shù)的實(shí)例代碼
本文通過實(shí)例代碼給大家介紹了mybatis動(dòng)態(tài)插入list,Mybatis 傳入List參數(shù)的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2018-04-04

