MybatisPlus出現(xiàn)Error attempting to get column ‘xxx字段‘ from result set異常解決
MybatisPlus如何處理實(shí)體枚舉類型轉(zhuǎn)換的教程可以參考:點(diǎn)擊查看教程,本文重點(diǎn)分析使用@EnumValue注解轉(zhuǎn)換時(shí)遇到的一下錯(cuò)誤原因,以及解決方案。
一、背景描述
在操作MybatisPlus的實(shí)體屬性一般都是基本類型或者對(duì)應(yīng)的引用類型或者String類型。但是MySQL8早已支持enum枚舉類型,一直都沒有實(shí)際操作過(guò),于是想著有個(gè)枚舉的場(chǎng)景打算實(shí)際項(xiàng)目里面用一下。當(dāng)時(shí)在具體數(shù)據(jù)庫(kù)表中設(shè)計(jì)了一個(gè)字段state來(lái)表示狀態(tài),這個(gè)狀態(tài)有3個(gè)值:已入組、已出組、已移除。于是設(shè)計(jì)了這個(gè)字段為enum類型屬性。但是在具體查詢的時(shí)候出現(xiàn)如下的錯(cuò)誤:

二、案例分析
當(dāng)時(shí)具體場(chǎng)景比較簡(jiǎn)單就兩個(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;
/**
* 身份證號(hào)
*/
@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啟動(dòng)都會(huì)報(bào)錯(cuò),具體原因是因?yàn)镸ybatisePlus實(shí)現(xiàn)了根據(jù)這個(gè)注解表示實(shí)體屬性自動(dòng)枚舉類型轉(zhuǎn)換。如果找不到就會(huì)報(bào)錯(cuò)。
*/
@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 '身份證號(hào)',
`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='枚舉測(cè)試表';
三、單元測(cè)試
@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í)行以上單元測(cè)試會(huì)出現(xiàn)上面的錯(cuò)誤,這里我就再貼一下圖:

四、問(wè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)行上面的單元測(cè)試方法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è)方法無(wú)論誰(shuí)調(diào)用都是會(huì)拋出SQLFeatureNotSupportedException異常,那這樣的話這個(gè)方法又有什么意義呢,于是猜想著是不是當(dāng)前的druid是1.1.16(從下圖可以看出版本依賴)版本太低導(dǎo)致無(wú)法適配當(dāng)前查詢場(chǎng)景,既然版本太低那就升級(jí)一下druid版本到1.1.21。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>

升級(jí)版本1.1.21繼續(xù)嘗試著運(yùn)行,發(fā)現(xiàn)確實(shí)成功解決了。從下圖可以看出druid版本成功升級(jí)從黃色區(qū)域可以看出來(lái),那為什么可以解決當(dāng)前問(wèn)題呢?于是嘗試進(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":"已出組"}]
五、其他問(wèn)題
alibaba.fastjson序列化枚舉時(shí)候顯示一個(gè)int值得問(wèn)題,其實(shí)這個(gè)int值就是枚舉中的ordinary也就是枚舉列表中的索引。這個(gè)了解java枚舉的應(yīng)該都清楚枚舉列表中的值都有自己對(duì)應(yīng)的所有,而且底層也是存儲(chǔ)在一個(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatis異常java.sql.SQLSyntaxErrorException的問(wèn)題解決
- Mybatis操作數(shù)據(jù)時(shí)出現(xiàn):java.sql.SQLSyntaxErrorException:?Unknown?column?'XXX'?in?'field?list'的問(wèn)題解決
- MybatisPlusException:Failed?to?process,Error?SQL異常報(bào)錯(cuò)的解決辦法
- Mybatis配置錯(cuò)誤:java.lang.ExceptionInInitializerError
- MybatisPlus BaseMapper 中的方法全部 Invalid bound statement (not found Error處理)
- 解決Mybatis出現(xiàn)報(bào)錯(cuò)Error querying database.Cause: java.lang.IndexOutOfBoundsException: Index 9 out of
相關(guān)文章
JAVA?DOC如何生成標(biāo)準(zhǔn)的JAVA?API文檔詳解
這篇文章主要給大家介紹了關(guān)于JAVA?DOC如何生成標(biāo)準(zhǔn)的JAVA?API文檔的相關(guān)資料,Javadoc是Sun公司提供的一種工具,它可以從程序源代碼中抽取類、方法、成員等注釋,然后形成一個(gè)和源代碼配套的API幫助文檔,需要的朋友可以參考下2024-06-06
Java報(bào)錯(cuò):java.lang.UnsatisfiedLinkError問(wèn)題的解決辦法
在Java開發(fā)中,java.lang.UnsatisfiedLinkError是一種與本地方法調(diào)用相關(guān)的常見異常,本文將詳細(xì)分析這一異常的背景、可能的原因、錯(cuò)誤代碼示例、正確代碼示例,以及編寫代碼時(shí)需要注意的事項(xiàng),需要的朋友可以參考下2024-09-09
Java提取HTML文本內(nèi)容的兩種輕量級(jí)實(shí)現(xiàn)方案對(duì)比
在日常的 Java 開發(fā)中,我們經(jīng)常會(huì)遇到處理 HTML 內(nèi)容的場(chǎng)景,本文將介紹兩種處理思路,一種是利用第三方文檔處理庫(kù)將 HTML 作為文檔解析,另一種是主流的輕量級(jí) HTML 解析器方案,大家可以根據(jù)自己的需求進(jìn)行選擇2026-04-04
SpringMVC Restful api接口實(shí)現(xiàn)的代碼
本篇文章主要介紹了SpringMVC Restful api接口實(shí)現(xiàn)的代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09
Java中ShardingSphere分庫(kù)分表實(shí)戰(zhàn)
我們做項(xiàng)目的時(shí)候,數(shù)據(jù)量比較大,單表千萬(wàn)級(jí)別的,需要分庫(kù)分表,本文主要介紹了Java中ShardingSphere分庫(kù)分表實(shí)戰(zhàn),感興趣的可以了解一下2021-09-09
SpringMVC中常用參數(shù)校驗(yàn)類注解使用示例教程
這篇文章主要介紹了SpringMVC中常用參數(shù)校驗(yàn)類注解使用示例教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03
SpringBoot通過(guò)token實(shí)現(xiàn)用戶互踢功能(具體實(shí)現(xiàn))
所謂token,既用戶能夠在一定時(shí)間內(nèi)證明自己身份的一長(zhǎng)串字符串,這篇文章主要介紹了SpringBoot通過(guò)token實(shí)現(xiàn)用戶互踢功能,需要的朋友可以參考下2024-04-04
SpringBoot項(xiàng)目訪問(wèn)任意接口出現(xiàn)401錯(cuò)誤的解決方案
今天小編就為大家分享一篇關(guān)于SpringBoot項(xiàng)目訪問(wèn)任意接口出現(xiàn)401錯(cuò)誤的解決方案,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01

