您好,登錄后才能下訂單哦!
本篇內容主要講解“MyBatis-Plus 用枚舉自動關聯注入”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“MyBatis-Plus 用枚舉自動關聯注入”吧!
什么是枚舉自動注入?
實際效果
實現步驟
踩坑
解決方法
參數解析
總結
官方文檔是這么解釋的
解決了繁瑣的配置,讓 mybatis 優雅的使用枚舉屬性!
按我的理解是維護在內存中且不易修改的輕量級字典。目前覺得這個功能的使用場景相對有限,但是如果有用到的話開箱即用也是很棒的。廢話不多說,接下來讓我們看一下它的實際效果吧。
通常情況下,我們會這樣聲明一個用戶實體
public class User { private String id; private String name; private Integer age; private String phone; //省略getter&setter&constructor ... }
那么最終獲取到的JSON數據應該類似于這樣
{ id: "1", name: "張三", age: 18, phone: "10000" }
如若使用MyBatis-Plus的枚舉自動關聯注入,可以更優雅的實現如下效果
{ id: "1", name: "張三", age: "十八歲", phone: "中國電信" }
實現過程僅有三步且非常簡單,代碼量也非常的少,下面介紹一下實現步驟。
1.創建兩個枚舉對象,分別為AgeEnum與PhoneEnum,這里使用枚舉建立一個映射關系。
public enum AgeEnum implements IEnum { ONE(1, "一歲"), TWO(2, "二歲"); private int age; private String desc; AgeEnum(final int age, final String desc) { this.age = age; this.desc = desc; } @Override public Serializable getValue() { return this.age; } @JsonValue public String getDesc(){ return this.desc; } }
public enum PhoneEnum implements IEnum { CMCC("10086", "中國移動"), CUCC("10010", "中國聯通"), CT("10000", "中國電信"); private String phone; private String desc; PhoneEnum(final String phone, final String desc) { this.phone = phone; this.desc = desc; } @Override public Serializable getValue() { return this.phone; } @JsonValue public String getDesc(){ return this.desc; } }
注意:
@JsonValue是使用JackSon解析時有效,若使用fastjson,請看官方文檔提供的解決方案
不要把@JsonValue打成@JsonView了,否則自動關聯注入的是枚舉名(name屬性),如下所示
別忘記實現IEnum接口,否則自動關聯注入的是枚舉名(name屬性),如下所示
{ id: "1", name: "張三", age: "十八歲", phone: "CT" }
2.將User實體中的屬性替換為枚舉,例如
public class User { private String id; private String name; private AgeEnum age; private PhoneEnum phone; //省略getter&setter&constructor ... }
3.配置掃描枚舉,添加如下配置
mybatis-plus.typeEnumsPackage=com.xxx.xxx.enums//枚舉所在路徑
至此,使用MyBatis-Plus的枚舉自動關聯注入就完成了。
在使用枚舉自動關聯注入時,還踩了一個坑。在代碼正確的情況下出現了如下問題。
{ id: null, name: null, age: null, phone: null }
查出的所有值都為null,通過DEBUG跟蹤代碼發現問題。數據庫中將實體中的某個枚舉屬性設置為了tinyint類型,在數據庫中存儲的值是1,枚舉中也是使用1來映射關系,然而MyBaits-Plus在獲取值是卻讀成了true,因此枚舉并沒有映射成功,返回null值。
當獲取IsEnableEnum的枚舉時,會執行這行代碼獲取枚舉中的關系映射
EnumUtils.valueOf(this.type, rs.getObject(columnName));
但是MyBatis讀取到的值變成了true
無法正確匹配到映射的值,返回null值,IsEnableEnum中聲明的映射關系如下。
ENABLE(1, "可用"), LIMIT(-1, "禁用");
1.將表中IsEnableEnum枚舉對應的字段is_enable類型由tinyint改為int即可,這種解決方法的優點就是不用修改代碼就解決問題。
2.MySQL中tinyint(1)對應Java中的boolean類型,非0為true,0為false。因此修改IsEnableEnum中的映射關系,如下。
ENABLE(true, "可用"), LIMIT(false, "禁用");
當使用枚舉注入的方式時,作為參數解析如果不注意會出現解析異常的情況。這里以修改User的is_enable值(數據庫表中字段屬性設置為int)為例看下具體解析異常情況的問題。例如,我們需要通過下面這個接口接收JSON請求參數來修改用戶的信息。
@PostMapping public User saveUser(@RequestBody User user) { return userService.insertOrUpdate(user) ? userService.selectById(user.getId()) : null; }
使用Postman模擬請求,JSON參數
{ "id":"922000984245391362", "isEnable":-1 }
響應結果
{ "timestamp": "2018-05-12T04:20:15.920+0000", "status": 400, "error": "Bad Request", "exception": "org.springframework.http.converter.HttpMessageNotReadableException", "message": "JSON parse error: Can not deserialize value of type com.github.common.domain.enums.IsEnableEnum from number -1: index value outside legal index range [0..1]; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type com.github.common.domain.enums.IsEnableEnum from number -1: index value outside legal index range [0..1]\n at [Source: java.io.PushbackInputStream@25386a8e; line: 3, column: 13] (through reference chain: com.github.common.domain.User[\"isEnable\"])", "path": "/" }
從錯誤信息我們可知,無法將-1映射成IsEnableEnum枚舉,可用范圍是0..1,那么應該怎么解決呢?
自己摸索出的解決方式有兩種,分別為
使用value屬性映射,經過測試0對應的是ENABLE(1, "可用"),1對應的是LIMIT(-1, "禁用")。很奇葩吧,因此不推薦此方式。
使用desc屬性映射,將JSON請求參數改成如下就可以解析成功不報錯。
{ "id":"922000984245391362", "isEnable":"禁用" }
MyBatis-Plus這個特性目前用的還是不多,本質上其實還是把映射關系寫死在代碼中且個人覺得設計有些許不合理的地方,并不能替代字典,因此還是推薦使用字典方式,可以動態的修改映射關系。當項目遇到希望使用比字典更輕更快更容易上手的場景時,可以嘗試使用枚舉注入的方式。
針對于解決方法的選擇個人想法是,當存儲的值僅有兩個且關系相對時,可以使用方法二,而在任何場景下方法一都適用,因此個人比較推薦方法一,因為可以存儲更多的值和映射關系,例如上文的電話號碼枚舉。
最后,貼上MyBatis-Plus的官方文檔,強烈推薦小伙伴們去嘗試使用,非常棒的一個開源項目。
到此,相信大家對“MyBatis-Plus 用枚舉自動關聯注入”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。