MyBatis在DAO層定義接口返回類型泛型無效的解決
MyBatis DAO層定義接口返回類型泛型無效
今天很偶然的因為一次粗心而發(fā)現(xiàn)的一個mybatis問題,這里就寫出來與大家分享一下。

DAO層定義了一個接口,返回String集合,用于獲取最熱門的搜索信息。

mapper.xml文件接口返回的類型卻是search對象。

調(diào)用接口,返回的是search對象集合,沒有報錯,泛型沒起到作用。
仔細一想,泛型是在編譯階段將我們的返回值類型匹配到一具體類型,而DAO層的接口卻沒有具體的返回值信息,所以在編譯階段它是可以通過的,這也就是說我們在DAO層定義的接口返回值泛型是不起作用的,具體的類型還是得依靠mapper.xml文件中定義的返回值類型為準。
那如果我們定義了泛型,并根據(jù)泛型來操作數(shù)據(jù)是不是會報錯呢?
我特地實驗了一番。mapper.xml查詢實際返回的是Person對象,而我使用的Animal對象集合去接收,并對集合進行了遍歷操作




最后報了ClassCastException,所以得出結(jié)論,DAO層接口定義的返回值泛型是沒有用的,實際返回需要根據(jù)具體的mapper.xml文件對應的方法返回值來確定。
但是我們卻可以根據(jù)泛型類型來進行數(shù)據(jù)的操作,這也不算是bug,只是泛型和mybatis沒有很好的融合吧,個人理解。
注意:
mybatis的DAO層接口與mapper.xml文件的對應是通過代理類來實現(xiàn)的,有兩種方式,一種是通過namespace來對應,一種是放在同一路徑下,但是要確保接口文件和xml文件名字相同。
MyBatis返回類型
分類及返回值類型
對應的分類為
1、resultMap
2、resultType
對應返回值類型
1、resultMap:結(jié)果集
2、resultType:int,string ,long ,class
要點
在MyBatis進行查詢映射時,其實查詢出來的每一個屬性都是放在一個對應的Map里面的,其中鍵是屬性名,值則是其對應的值。
1、當提供的返回類型屬性是resultType時,MyBatis會將Map里面的鍵值對取出賦給resultType所指定的對象對應的屬性。所以其實MyBatis的每一個查詢映射的返回類型都是ResultMap,只是當提供的返回類型屬性是resultType的時候,MyBatis對自動的給把對應的值賦給resultType所指定對象的屬性。
2、當提供的返回類型是resultMap時,因為Map不能很好表示領(lǐng)域模型,就需要自己再進一步的把它轉(zhuǎn)化為對應的對象,這常常在復雜查詢中很有作用。
示例
resultMap案例
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >
select
<include refid="Base_Column_List" />
from common_car_make
where id = #{id,jdbcType=BIGINT}
</select>
resultType--long案例
<select id="queryCarTypeByModelIdCount" resultType="java.lang.Long" parameterType="java.util.Map">
select count(*) from common_car_type cm
where 1=1
<if test="carModelId != null">
and cm.car_model_id = #{carModelId,jdbcType=DECIMAL}
</if>
</select>
resultType--int案例
<select id="queryCategoryBrandCount" resultType="java.lang.Integer" parameterType="java.util.HashMap" >
select count(1)
from common_category_brand
where 1=1
<if test="categoryId != null" >
and category_id = #{categoryId,jdbcType=BIGINT}
</if>
<if test="brandId != null" >
and brand_id = #{brandId,jdbcType=BIGINT}
</if>
</select>
resultType--class案例:查詢結(jié)果對應類中的屬性值
<select id="selectCommonBrand" resultType="com.epeit.api.model.CommonBrandPo" parameterType="java.lang.Long" >
select id, brand_name brandName, brand_type brandType, icon, delete_flag deleteFlag
from common_brand
where id = #{id,jdbcType=BIGINT}
</select>
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
在java中 利用匿名內(nèi)部類進行較簡潔的雙括弧初始化的方法
本篇文章小編將為大家介紹,關(guān)于在java中 利用匿名內(nèi)部類進行較簡潔的雙括弧初始化的方法,有需要的朋友可以參考一下2013-04-04
基于springboot創(chuàng)建mybatis的完整步驟
MyBatis是一款優(yōu)秀的數(shù)據(jù)庫持久層框架,相比Hibernate我更喜歡使用MyBatis,看的到SQL還是讓人更安心點,這篇文章主要給大家介紹了關(guān)于基于springboot創(chuàng)建mybatis的完整步驟,需要的朋友可以參考下2024-03-03
Java字符串相關(guān)類StringBuffer的用法詳解
java.lang包下的StringBuffer類,代表著可變的字符序列,可以用來對字符串內(nèi)容進行增刪改操作。本文將通過示例詳細說說它的用法,感興趣的可以跟隨小編一起學習一下2022-10-10
SpringBoot中使用@Async實現(xiàn)異步任務(wù)調(diào)用詳解
這篇文章主要介紹了SpringBoot中使用@Async實現(xiàn)異步任務(wù)調(diào)用詳解,一個可以無需等待被調(diào)用函數(shù)的返回值就讓操作繼續(xù)進行的方法(來自百度百科),即程序在順序執(zhí)行時,不等待異步調(diào)用的語句返回結(jié)果就執(zhí)行后面的程序,需要的朋友可以參考下2023-12-12

