MyBatis高級(jí)映射ResultMap解決屬性問題
ResultMap結(jié)果映射解決復(fù)雜屬性
之前我們提到了用resultMap解決數(shù)據(jù)表中字段名與bean屬性名不一致的問題,這是resultMap的一種簡(jiǎn)單實(shí)現(xiàn)。下面我們來看如何利用ResultMap來解決更復(fù)雜的屬性問題
場(chǎng)景:當(dāng)我們需要聯(lián)查兩張表的時(shí)候,通常會(huì)在sql層面對(duì)兩個(gè)表進(jìn)行外鍵關(guān)聯(lián)。那么設(shè)置了外鍵的從表對(duì)應(yīng)的實(shí)體Bean中就需要定義一個(gè)對(duì)應(yīng)主表的實(shí)例對(duì)象。
多對(duì)一關(guān)系處理
按照查詢嵌套
示例:
// 學(xué)生表 從表
public class Student {
private int id;
private String name;
private Teacher teacher; // 定義主表對(duì)應(yīng)bean實(shí)例
// 教師表 主表
public class Teacher {
private int id;
private String name;
//teacher接口中定義方法
@Select("select name from teacher where id = #{tid}")
Teacher getTeacherById(@Param("tid") int id);
// student接口中定義方法
List<Student> getStudent();
sql:
-- 可以直接利用多表聯(lián)查sql 但是最終無法正確輸出teacher類信息
select * from student s join teacher t on s.tid = t.id;
-- 將上面的sql拆開成兩句 先查詢到學(xué)生信息 用學(xué)生的tid字段對(duì)應(yīng)教師的id查詢教師
select * from student;
select * from teacher where id = #{tid}
打印日志:
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@79da8dc5]
==> Preparing: select * from student;
==> Parameters:
<== Columns: id, name, tid
<== Row: 1, 小子三, 1
<== Row: 2, 小子四, 1
<== Row: 3, 小子五, 1
<== Row: 4, 小子六, 1
<== Row: 5, 小子七, 1
<== Row: 6, 小子八, 1
<== Total: 6
Student{id=1, name='小子三', teacher=null}
Student{id=2, name='小子四', teacher=null}
Student{id=3, name='小子五', teacher=null}
Student{id=4, name='小子六', teacher=null}
Student{id=5, name='小子七', teacher=null}
Student{id=6, name='小子八', teacher=null}
可以很清晰的看出sql一共只執(zhí)行了一條,而根據(jù)學(xué)生表tid字段查詢教師信息的sql根本就沒有運(yùn)行
下面我們對(duì)select * from teacher where id = #{tid}這句sql返回的結(jié)果配置,利用resultMap為其配置合理的結(jié)果集來接收查詢到的結(jié)果
resultMap及sql配置如下:
<resultMap id="studentTeacher" type="student"> <!-- 普通映射 --> <result column="id" property="id"/> <result column="name" property="name"/> <!-- 復(fù)雜映射 association對(duì)象 collection集合 --> <association property="teacher" column="tid" javaType="teacher" select="getTeacherById"/> <!-- student表中tid字段對(duì)應(yīng)實(shí)體類student中的teacher屬性 對(duì)應(yīng)程序中的teacher類型 執(zhí)行select語句 --> </resultMap>
最終打印結(jié)果如下:
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@79da8dc5]
// 執(zhí)行sql1
==> Preparing: select * from student;
==> Parameters:
<== Columns: id, name, tid
<== Row: 1, 小子三, 1
// 執(zhí)行sql1
====> Preparing: select * from teacher where id = ?
====> Parameters: 1(Integer)
<==== Columns: id, name
<==== Row: 1, 秦老師
<==== Total: 1
<== Row: 2, 小子四, 1
<== Row: 3, 小子五, 1
<== Row: 4, 小子六, 1
<== Row: 5, 小子七, 1
<== Row: 6, 小子八, 1
<== Total: 6
// 最終teacher也以對(duì)象的形式打印出來
Student{id=1, name='小子三', teacher=Teacher{id=1, name='秦老師'}}
Student{id=2, name='小子四', teacher=Teacher{id=1, name='秦老師'}}
Student{id=3, name='小子五', teacher=Teacher{id=1, name='秦老師'}}
Student{id=4, name='小子六', teacher=Teacher{id=1, name='秦老師'}}
Student{id=5, name='小子七', teacher=Teacher{id=1, name='秦老師'}}
Student{id=6, name='小子八', teacher=Teacher{id=1, name='秦老師'}}
按照結(jié)果嵌套
studentMapper.xml配置resultMap如下:
<!-- 按照結(jié)果嵌套 -->
<select id="getStudent2" resultMap="studentTeacher2">
select s.id sid,s.name sname,t.id tid,t.name tname from student s join teacher t on s.tid = t.id;
</select>
<resultMap id="studentTeacher2" type="student">
<result column="sid" property="id"/>
<result column="sname" property="name"/>
<association property="teacher" javaType="teacher">
<result column="tid" property="id"/>
<result property="name" column="tname"/>
</association>
</resultMap>
如果采用結(jié)果嵌套配置,此時(shí)不論bean類屬性是否是基本類型都需要用result進(jìn)行映射,否則輸出結(jié)果就會(huì)采用默認(rèn)值
一對(duì)多關(guān)系處理
一對(duì)多關(guān)系處理,依舊以上述老師和學(xué)生為例。但是實(shí)體類需要修改,如下:
public class Teacher {
private int id;
private String name;
private List<Student> student;
public class Student {
private int id;
private String name;
private int tid;
一個(gè)老師下對(duì)應(yīng)多個(gè)學(xué)生,所以我們定義一個(gè)集合用于存儲(chǔ)學(xué)生
下面嘗試獲取指定老師下的所有學(xué)生信息及該老師信息
按照結(jié)果嵌套
程序:
// TeacherMapper
// 指定老師下面的所有學(xué)生
Teacher getTeaById(@Param("teaId") int id);
resultMap配置
<select id="getTeaById" resultMap="TeaStu">
select s.id sid, s.name sname, t.name tname, t.id tpid,s.tid
from student s ,teacher t
where t.id = s.tid and t.id = #{teaId};
</select>
<resultMap id="TeaStu" type="Teacher">
<result column="tpid" property="id"/>
<result column="tname" property="name"/>
<collection property="student" ofType="student">
<result column="sid" property="id"/>
<result column="sname" property="name"/>
<result column="tid" property="tid" />
</collection>
</resultMap>
因?yàn)閺?fù)雜屬性的類型為集合,所以我們?cè)谂渲胷esultMap結(jié)果集映射時(shí)不再使用association對(duì)象,換成collection集合。在配置collection與association不同的是將JavaType(Java類型)換成了OfType其他依舊不變
按照查詢嵌套
TeacherMapper.xml配置resultMap
<select id="getTeaById" resultMap="TeaStu2">
select id,name from teacher where id = #{teaId}
</select>
<resultMap id="TeaStu2" type="teacher">
<result column="id" property="id"/>
<result column="name" property="name"/>
<collection property="student" javaType="ArrayList" ofType="student" select="getStuList" column="id"/>
</resultMap>
<select id="getStuList" resultType="student">
select id,name,tid from student where tid = #{tid}
</select>
小結(jié):個(gè)人感覺,按照查詢嵌套雖然一定程度上簡(jiǎn)化了sql語句的編寫,但是針對(duì)resultMap的配置極其復(fù)雜,如果使用次數(shù)多可能還好。建議使用按照結(jié)果嵌套,sql語句編寫雖然復(fù)雜一些但是只要基礎(chǔ)扎實(shí)都是有理可循的,而且sql的編寫你可以在數(shù)據(jù)庫中進(jìn)行調(diào)試,選擇最優(yōu)sql,并且對(duì)于結(jié)果集的映射配置也比較簡(jiǎn)單,容易理解。
也可能是初學(xué)所以覺得按照子查詢會(huì)有點(diǎn)難度,總之還是水平太低了
到此這篇關(guān)于MyBatis高級(jí)映射ResultMap解決屬性問題的文章就介紹到這了,更多相關(guān)MyBatis高級(jí)映射ResultMap內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatis高級(jí)映射學(xué)習(xí)教程
- MyBatis高級(jí)映射和查詢緩存
- Mybatis高級(jí)映射、動(dòng)態(tài)SQL及獲得自增主鍵的解析
- mybatis高級(jí)映射一對(duì)多查詢實(shí)現(xiàn)代碼
- 基于mybatis高級(jí)映射多對(duì)多查詢的實(shí)現(xiàn)
- javaMybatis映射屬性,高級(jí)映射詳解
- 解析Mybatis延遲加載問題
- MyBatis延遲加載與立即加載案例教程
- Mybatis中的延遲加載,以及原理分析
- MyBatis實(shí)現(xiàn)高級(jí)映射的示例代碼
- 詳解MyBatis延遲加載是如何實(shí)現(xiàn)的
- MyBatis高級(jí)映射及延遲加載的實(shí)現(xiàn)
相關(guān)文章
Java類之間的關(guān)系圖_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
在Java以及其他的面向?qū)ο笤O(shè)計(jì)模式中,類與類之間主要有6種關(guān)系,他們分別是:依賴、關(guān)聯(lián)、聚合、組合、繼承、實(shí)現(xiàn)。他們的耦合度依次增強(qiáng),有興趣的可以了解一下2017-08-08
SpringBoot整合iText7導(dǎo)出PDF及性能優(yōu)化方式
在SpringBoot項(xiàng)目中整合iText7庫以導(dǎo)出PDF文件,不僅能夠滿足報(bào)告生成需求,而且可以處理復(fù)雜的文檔布局與樣式,整合步驟包括添加Maven依賴、編寫PDF生成代碼,性能優(yōu)化方面,建議使用流式處理、緩存樣式與字體、優(yōu)化HTML/CSS結(jié)構(gòu)、采用異步處理2024-09-09
java實(shí)現(xiàn)簡(jiǎn)單發(fā)送郵件功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單發(fā)送郵件功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
java awt實(shí)現(xiàn)計(jì)算器功能
這篇文章主要為大家詳細(xì)介紹了java awt實(shí)現(xiàn)計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12
淺談SpringBoot 中關(guān)于自定義異常處理的套路
這篇文章主要介紹了淺談SpringBoot 中關(guān)于自定義異常處理的套路,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04

