MybatisPlus出現(xiàn)Error attempting to get column ‘xxx字段‘ from result set異常解決
MybatisPlus
如何處理實(shí)體枚舉類型轉(zhuǎn)換的教程可以參考:點(diǎn)擊查看教程,本文重點(diǎn)分析使用@EnumValue
注解轉(zhuǎn)換時(shí)遇到的一下錯誤原因,以及解決方案。
一、背景描述
在操作MybatisPlus
的實(shí)體屬性一般都是基本類型
或者對應(yīng)的引用類型
或者String
類型。但是MySQL8早已支持enum
枚舉類型,一直都沒有實(shí)際操作過,于是想著有個(gè)枚舉的場景打算實(shí)際項(xiàng)目里面用一下。當(dāng)時(shí)在具體數(shù)據(jù)庫表中設(shè)計(jì)了一個(gè)字段state
來表示狀態(tài),這個(gè)狀態(tài)有3個(gè)值:已入組
、已出組
、已移除
。于是設(shè)計(jì)了這個(gè)字段為enum
類型屬性。但是在具體查詢的時(shí)候出現(xiàn)如下的錯誤:
二、案例分析
當(dāng)時(shí)具體場景比較簡單就兩個(gè)類:實(shí)體類
、枚舉類
實(shí)體類(demo)
實(shí)體類的定義具體如下,重點(diǎn)關(guān)注屬性:state
@Data @EqualsAndHashCode @TableName("demo") public class Demo implements Serializable { private static final long serialVersionUID = 1L; /** * 主鍵 */ @TableId(value = "id", type = IdType.AUTO) private Integer id; /** * 身份證號 */ @TableField("id_card") private String idCard; /** * 受試者姓名 */ @TableField("`name`") private String name; /** * 聯(lián)系電話 */ @TableField("phone") private String phone; /** * 入組時(shí)間 */ @TableField("join_time") private Date joinTime; /** * 狀態(tài):已入組、已出組、已移除 */ @TableField("state") private DemoStateEnum state; /** * 最近一次操作的用戶 */ @TableField("last_user") private String lastUser; /** * 關(guān)聯(lián)項(xiàng)目ID */ @TableField("project_id") private Integer projectId; /** * 最后一次操作時(shí)間 */ @TableField("last_update") private Date lastUpdate; public static Demo builder(){ return new Demo(); } }
枚舉類(DemoStateEnum)
public enum DemoStateEnum { JOINED("已入組"), OUTED("已出組"), REMOVED("已移除"); /** * 注意這個(gè) @EnumValue注解一定要加上,否則SpringBoot啟動都會報(bào)錯,具體原因是因?yàn)镸ybatisePlus實(shí)現(xiàn)了根據(jù)這個(gè)注解表示實(shí)體屬性自動枚舉類型轉(zhuǎn)換。如果找不到就會報(bào)錯。 */ @EnumValue private String state; DemoStateEnum(String state){ this.state = state; } /** * @JSONField這個(gè)注解解決alibaba.fastjson序列化是枚舉顯示的索引的值,而我們想要的顯示是具體的值:已入組、已出組、已移除等。 */ @JSONField public String getState() { return state; } @Override public String toString() { return "DemoStateEnum{" + "state='" + state + '\'' + '}'; } }
表結(jié)構(gòu)
CREATE TABLE `demo` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '主鍵', `id_card` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '身份證號', `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '受試者姓名', `phone` varchar(13) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '聯(lián)系電話', `join_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '入組時(shí)間', `state` enum('已入組','已出組','已移除') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '狀態(tài):已入組、已出組、已移除', `last_user` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '最近一次操作的用戶', `project_id` int NOT NULL COMMENT '關(guān)聯(lián)項(xiàng)目ID', `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后一次操作時(shí)間', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='枚舉測試表';
三、單元測試
@SpringBootTest public class DemoTest { @Autowired private DemoMapper deemoMapper; //查詢所有demo數(shù)據(jù) @Test public void querySubject() throws JsonProcessingException { List<Demo> demos = deemoMapper.selectList(null); System.err.println(JSON.toJSONString(demos)); } }
執(zhí)行以上單元測試會出現(xiàn)上面的錯誤,這里我就再貼一下圖:
四、問題分析
# 根據(jù)上圖細(xì)看這句話 Caused by: java.sql.SQLFeatureNotSupportedException at com.alibaba.druid.pool.DruidPooledResultSet.getObject(DruidPooledResultSet.java:1771)
找到DruidPooledResultSet.getObject()
這個(gè)方法打上一個(gè)斷點(diǎn),然后根據(jù)idea的線程調(diào)用棧debug往上確定是由哪一步出現(xiàn)的異常。
如上圖設(shè)置好debug點(diǎn),開始運(yùn)行上面的單元測試方法querySubject
方法,監(jiān)聽斷點(diǎn):
那怎么知道上層是那個(gè)方法觸發(fā)了這個(gè)異常呢,接著看左邊的線程調(diào)用棧:可以看出黃色部分是上層真實(shí)異常的調(diào)用方。
基于以上我們繼續(xù)往下分析,可以發(fā)現(xiàn)MybatisEnumTypeHandler#getNullableResult(java.sql.ResultSet, java.lang.String)這個(gè)方法里面的ResultSet的具體參數(shù)類型是一個(gè)DruidPooledResultSet,然后再調(diào)用DruidPooledResultSet類中的getObject(String columnLabel, Class type)方法。
public <T> T getObject(String columnLabel, Class<T> type) throws SQLException { throw new SQLFeatureNotSupportedException(); }
顯然這個(gè)方法無論誰調(diào)用都是會拋出SQLFeatureNotSupportedException
異常,那這樣的話這個(gè)方法又有什么意義呢,于是猜想著是不是當(dāng)前的druid是1.1.16
(從下圖可以看出版本依賴)版本太低導(dǎo)致無法適配當(dāng)前查詢場景,既然版本太低那就升級一下druid版本到1.1.21
。
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.21</version> </dependency>
升級版本1.1.21
繼續(xù)嘗試著運(yùn)行,發(fā)現(xiàn)確實(shí)成功解決了。從下圖可以看出druid版本成功升級從黃色區(qū)域可以看出來,那為什么可以解決當(dāng)前問題呢?于是嘗試進(jìn)入同樣的DruidPooledResultSet類中的getObject(String columnLabel, Class type)方法。發(fā)現(xiàn)1.1.16
版本中的固定異常SQLFeatureNotSupportedException
沒有了,實(shí)現(xiàn)也完全不同了。如下:
public <T> T getObject(String columnLabel, Class<T> type) throws SQLException { try { // 正常調(diào)用JDBC中的ResultSet了,所以可以正常獲取數(shù)據(jù),不再出現(xiàn)那個(gè)異常了。 return this.rs.getObject(columnLabel, type); } catch (Throwable var4) { throw this.checkException(var4); } }
查詢成功:
[{"id":4,"idCard":"666666","joinTime":"2023-08-09 15:21:13","lastUpdate":"2023-08-09 15:21:13","lastUser":"test user","name":"test name 6","phone":"123123123","projectId":2,"state":"已出組"},{"id":5,"idCard":"666666","joinTime":"2023-08-09 15:22:28","lastUpdate":"2023-08-09 15:22:28","lastUser":"test user","name":"test name 6","phone":"123123123","projectId":2,"state":"已出組"},{"id":6,"idCard":"666666","joinTime":"2023-08-09 15:24:00","lastUpdate":"2023-08-09 15:24:00","lastUser":"test user","name":"test name 6","phone":"123123123","projectId":2,"state":"已出組"}]
五、其他問題
alibaba.fastjson序列化枚舉時(shí)候顯示一個(gè)int值得問題,其實(shí)這個(gè)int值就是枚舉中的ordinary也就是枚舉列表中的索引。這個(gè)了解java枚舉的應(yīng)該都清楚枚舉列表中的值都有自己對應(yīng)的所有,而且底層也是存儲在一個(gè)數(shù)組中的,也就是相當(dāng)于數(shù)組的下表。但是不希望在序列化的時(shí)候顯示這個(gè)下表,希望顯示state的值。如何解決,在枚舉的state屬性的get方法加上如下@JSONField
注解,這樣就可以顯示state的枚舉值了。
@JSONField public String getState() { return state; }
到此這篇關(guān)于MybatisPlus出現(xiàn)Error attempting to get column ‘xxx字段‘ from result set異常解決的文章就介紹到這了,更多相關(guān)mybatis ‘xx‘ from result set內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatis異常java.sql.SQLSyntaxErrorException的問題解決
- Mybatis操作數(shù)據(jù)時(shí)出現(xiàn):java.sql.SQLSyntaxErrorException:?Unknown?column?'XXX'?in?'field?list'的問題解決
- MybatisPlusException:Failed?to?process,Error?SQL異常報(bào)錯的解決辦法
- Mybatis配置錯誤:java.lang.ExceptionInInitializerError
- MybatisPlus BaseMapper 中的方法全部 Invalid bound statement (not found Error處理)
- 解決Mybatis出現(xiàn)報(bào)錯Error querying database.Cause: java.lang.IndexOutOfBoundsException: Index 9 out of
相關(guān)文章
Linux?Ubuntu系統(tǒng)下配置JDK環(huán)境、MySQL環(huán)境全過程
眾所周知Ubuntu是一種基于Linux的操作系統(tǒng),它提供了一個(gè)穩(wěn)定、安全和易于使用的環(huán)境,下面這篇文章主要給大家介紹了關(guān)于Linux?Ubuntu系統(tǒng)下配置JDK環(huán)境、MySQL環(huán)境的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-07-07Java list與set中contains()方法效率案例詳解
這篇文章主要介紹了Java list與set中contains()方法效率案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08java使用hadoop實(shí)現(xiàn)關(guān)聯(lián)商品統(tǒng)計(jì)
本篇文章java使用hadoop實(shí)現(xiàn)關(guān)聯(lián)商品統(tǒng)計(jì),可以實(shí)現(xiàn)商品的關(guān)聯(lián)統(tǒng)計(jì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-10-10Jenkin郵件收發(fā)實(shí)現(xiàn)原理及過程詳解
這篇文章主要介紹了Jenkin郵件收發(fā)實(shí)現(xiàn)原理及過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09