MyBatis高級(jí)映射及延遲加載的實(shí)現(xiàn)
多對(duì)一:
多種方式,常見(jiàn)的包括三種:
第一種方式:一條SQL語(yǔ)句,級(jí)聯(lián)屬性映射。
第二種方式:一條SQL語(yǔ)句,association。
第三種方式:兩條SQL語(yǔ)句,分步查詢。(這種方式常用:優(yōu)點(diǎn)一是可復(fù)用。優(yōu)點(diǎn)二是支持懶加載。)
怎么區(qū)分主表和副表?
原則:誰(shuí)在前面誰(shuí)是主表
例如:多對(duì)一,多在前面,那么多的那個(gè)表就是主表
級(jí)聯(lián)屬性映射:
Student類(lèi):
package pojo; /** * 學(xué)生信息 * 沒(méi)有cid這個(gè)屬性,后期會(huì)有特殊的方式來(lái)處理這個(gè)關(guān)系字段 */ public class Student { private Integer sid; private String sname; private Clazz clazz; public Clazz getClazz() { return clazz; } public void setClazz(Clazz clazz) { this.clazz = clazz; } @Override public String toString() { return "Student{" + "sid=" + sid + ", sname='" + sname + '\'' + ", clazz=" + clazz + '}'; } public Student() { } public Student(Integer sid, String sname) { this.sid = sid; this.sname = sname; } public Integer getSid() { return sid; } public void setSid(Integer sid) { this.sid = sid; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } }
對(duì)應(yīng)的sql映射文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="mapper.StudentMapper"> <!-- 級(jí)聯(lián)屬性映射 --> <resultMap id="studentResultMap" type="Student"> <id property="sid" column="sid"/> <result property="sname" column="sname"/> <result property="clazz.cid" column="cid"/> <result property="clazz.cname" column="cname"/> </resultMap> <select id="selectById" resultMap="studentResultMap"> SELECT s.sid, s.sname, c.cid, c.cname FROM t_student_plus s LEFT JOIN t_clazz c ON s.cid = c.cid WHERE s.sid = #{sid} </select> </mapper>
@Test public void testSelectBySid(){ StudentMapper mapper = SqlSessionUtil.openSession().getMapper(StudentMapper.class); Student student = mapper.selectBySid(1); System.out.println(student); }
sql語(yǔ)句:
2024-10-14 13:29:58.511 [main] DEBUG mapper.StudentMapper.selectById - ==> Preparing:
SELECT s.sid, s.sname, c.cid, c.cname FROM t_student_plus s
LEFT JOIN t_clazz c ON s.cid = c.cid WHERE s.sid = ?
association
對(duì)應(yīng)的sql映射文件:
<resultMap id="studentResultMapAssociation" type="Student"> <id property="sid" column="sid"/> <result property="sname" column="sname"/> <!-- 嵌套映射,將 clazz 對(duì)象中的 cid 和 cname 映射 --> <association property="clazz" javaType="Clazz"> <id property="cid" column="cid"/> <result property="cname" column="cname"/> </association> </resultMap> <select id="selectByIdAssociation" resultMap="studentResultMap"> SELECT s.sid, s.sname, c.cid, c.cname FROM t_student_plus s LEFT JOIN t_clazz c ON s.cid = c.cid WHERE s.sid = #{sid} </select>
association翻譯為:關(guān)聯(lián)。 學(xué)生對(duì)象關(guān)聯(lián)一個(gè)班級(jí)對(duì)象。
關(guān)鍵點(diǎn)說(shuō)明
<resultMap>
元素:resultMap
用于映射結(jié)果集到 Java 對(duì)象。通過(guò)定義StudentResultMap
來(lái)描述如何將查詢結(jié)果映射到Student
對(duì)象。<association>
元素:<association>
用于處理多對(duì)一的關(guān)系映射。它會(huì)把clazz
的數(shù)據(jù)映射到Student
對(duì)象的clazz
屬性上。property
:對(duì)應(yīng)Student
類(lèi)中的clazz
屬性。javaType
:指定Clazz
類(lèi)的全限定名。- 通過(guò)
property
和column
進(jìn)行字段的映射。
SQL 查詢:
selectStudentWithClazz
查詢使用了LEFT JOIN
來(lái)同時(shí)獲取student
和clazz
的信息,并通過(guò)resultMap
映射到Student
對(duì)象中。
分步查詢
<resultMap id="studentResultMapByStep" type="Student"> <id property="sid" column="sid"/> <id property="sname" column="sname"/> <association property="clazz" select="mapper.ClazzMapper.selectByCid" column="cid"/> </resultMap> <!--兩條sql語(yǔ)句,完成多對(duì)一的分布查詢--> <!-- 這是第一步,根據(jù)id值查詢學(xué)生的所有信息,這些信息當(dāng)中含有班級(jí)id(cid--> <select id="selectByIdStep1" resultMap="studentResultMapByStep" > select sid,sname,cid from t_student_plus where sid = #{sid} </select>
解釋?zhuān)?/strong>
- <resultMap id="studentResultMap" type="Student">:定義了一個(gè)結(jié)果映射規(guī)則,結(jié)果將映射到 Student 對(duì)象中。
- <id property="sid" column="sid"/>:將數(shù)據(jù)庫(kù)中的 sid 列映射到 Student 類(lèi)的 sid 屬性,通常用于映射主鍵。
- <result property="sname" column="sname"/>:將數(shù)據(jù)庫(kù)中的 sname 列映射到 Student 類(lèi)的 sname 屬性。
- <association>:用于描述一個(gè)對(duì)象屬性與其他查詢之間的關(guān)聯(lián)。
- property="clazz":Student 類(lèi)中對(duì)應(yīng)的屬性名是 clazz,它表示學(xué)生所屬的班級(jí)。
- select="com.powernode.mybatis.mapper.ClazzMapper.selectByCid":指定調(diào)用的查詢方法,用于獲取 Clazz 信息。
- column="cid":指定當(dāng)前查詢結(jié)果中的 cid 列的值,將其作為參數(shù)傳遞給 selectByCid 方法。
在ClazzMapper接口中添加方法
public interface ClazzMapper { /** * 分布查詢第二步 * 根據(jù)cid獲取Clazz信息 * @param cid * @return */ Clazz selectByCid(Integer cid); }
ClazzMapper的sql映射文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="mapper.ClazzMapper"> <select id="selectByCid" resultType="Clazz"> select cid,cname from t_clazz where cid = #{cid} </select> </mapper>
執(zhí)行結(jié)果,可以很明顯看到先后有兩條sql語(yǔ)句執(zhí)行:
延遲加載
一對(duì)多延遲加載機(jī)制和多對(duì)一是一樣的。同樣是通過(guò)兩種方式:
第一種:fetchType="lazy"
<resultMap id="studentResultMapByStep" type="Student"> <id property="sid" column="sid"/> <id property="sname" column="sname"/> <association property="clazz" select="mapper.ClazzMapper.selectByCid" column="cid" fetchType="lazy"/> <!--添加延遲--> </resultMap> <!--兩條sql語(yǔ)句,完成多對(duì)一的分布查詢--> <!-- 這是第一步,根據(jù)id值查詢學(xué)生的所有信息,這些信息當(dāng)中含有班級(jí)id(cid--> <select id="selectByIdStep1" resultMap="studentResultMapByStep" > select sid,sname,cid from t_student_plus where sid = #{sid} </select>
第二種:修改全局的配置setting,lazyLoadingEnabled=true,如果開(kāi)啟全局延遲加載,想讓某個(gè)sql不使用延遲加載:fetchType="eager"
一對(duì)多
一對(duì)多的實(shí)現(xiàn),通常是在一的一方中有List集合屬性。
在Clazz類(lèi)中添加List<Student> stus; 屬性。
package pojo; import java.util.List; /** * 班級(jí)信息 */ public class Clazz { public Clazz() { } private Integer cid; private String cname; private List<Student> stus; public List<Student> getStus() { return stus; } @Override public String toString() { return "Clazz{" + "cid=" + cid + ", cname='" + cname + '\'' + ", stus=" + stus + '}'; } public void setStus(List<Student> stus) { this.stus = stus; } public Integer getCid() { return cid; } public void setCid(Integer cid) { this.cid = cid; } public String getCname() { return cname; } public void setCname(String cname) { this.cname = cname; } public Clazz(Integer cid, String cname) { this.cid = cid; this.cname = cname; } }
一對(duì)多的實(shí)現(xiàn)通常包括兩種實(shí)現(xiàn)方式:
- 第一種方式:collection
- 第二種方式:分步查詢
collection:
public interface ClazzMapper { /** * 根據(jù)cid獲取Clazz信息 * @param cid * @return */ Clazz selectByCid(Integer cid); /** * 根據(jù)班級(jí)編號(hào)查詢班級(jí)信息。同時(shí)班級(jí)中所有的學(xué)生信息也要查詢。 * @param cid * @return */ Clazz selectClazzAndStusByCid(Integer cid); }
<resultMap id="clazzResultMap" type="Clazz"> <id property="cid" column="cid"/> <result property="cname" column="cname"/> <collection property="stus" ofType="Student"> <id property="sid" column="sid"/> <result property="sname" column="sname"/> </collection> </resultMap> <select id="selectClazzAndStusByCid" resultMap="clazzResultMap"> select * from t_clazz c join t_student s on c.cid = s.cid where c.cid = #{cid} </select>
注意是ofType,表示“集合中的類(lèi)型”?。?!
分步查詢:
<resultMap id="clazzResultMap" type="Clazz"> <id property="cid" column="cid"/> <result property="cname" column="cname"/> <!--主要看這里--> <collection property="stus" select="com.powernode.mybatis.mapper.StudentMapper.selectByCid" column="cid"/> </resultMap> <!--sql語(yǔ)句也變化了--> <select id="selectClazzAndStusByCid" resultMap="clazzResultMap"> select * from t_clazz c where c.cid = #{cid} </select>
/** * 根據(jù)班級(jí)編號(hào)獲取所有的學(xué)生。 * @param cid * @return */ List<Student> selectByCid(Integer cid);
<select id="selectByCid" resultType="Student"> select * from t_student where cid = #{cid} </select>
延遲加載
一對(duì)多延遲加載機(jī)制和多對(duì)一是一樣的。同樣是通過(guò)兩種方式:
- 第一種:fetchType="lazy"
- 第二種:修改全局的配置setting,lazyLoadingEnabled=true,如果開(kāi)啟全局延遲加載,想讓某個(gè)sql不使用延遲加載:fetchType="eager"
到此這篇關(guān)于MyBatis高級(jí)映射及延遲加載的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)MyBatis高級(jí)映射及延遲加載內(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延遲加載問(wèn)題
- MyBatis延遲加載與立即加載案例教程
- MyBatis高級(jí)映射ResultMap解決屬性問(wèn)題
- Mybatis中的延遲加載,以及原理分析
- MyBatis實(shí)現(xiàn)高級(jí)映射的示例代碼
- 詳解MyBatis延遲加載是如何實(shí)現(xiàn)的
相關(guān)文章
Java實(shí)現(xiàn)的JSONUtil工具類(lèi)與用法示例
這篇文章主要介紹了Java實(shí)現(xiàn)的JSONUtil工具類(lèi)與用法,結(jié)合實(shí)例形式分析了Java操作json格式數(shù)據(jù)工具類(lèi)JSONUtil的定義與簡(jiǎn)單使用技巧,需要的朋友可以參考下2018-07-07Java中的HashMap和ConcurrentHashMap區(qū)別和適用場(chǎng)景
HashMap和ConcurrentHashMap在對(duì)null值的處理、線程安全性、性能等方面存在顯著的區(qū)別,HashMap允許鍵和值為null,適用于單線程環(huán)境下的數(shù)據(jù)存儲(chǔ)和查詢場(chǎng)景;而ConcurrentHashMap不允許鍵和值為null,適用多線程環(huán)境下的數(shù)據(jù)存儲(chǔ)和查詢場(chǎng)景,具有線程安全性和較高的并發(fā)性能2025-01-01Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之財(cái)務(wù)預(yù)算管理系統(tǒng)的實(shí)現(xiàn)
這是一個(gè)使用了java+SSM+Jsp+Mysql+Layui+Maven開(kāi)發(fā)的財(cái)務(wù)預(yù)算管理系統(tǒng),是一個(gè)畢業(yè)設(shè)計(jì)的實(shí)戰(zhàn)練習(xí),具有財(cái)務(wù)預(yù)算管理該有的所有功能,感興趣的朋友快來(lái)看看吧2022-02-02SpringBoot實(shí)現(xiàn)掃碼登錄的項(xiàng)目實(shí)踐
本文主要介紹了SpringBoot實(shí)現(xiàn)掃碼登錄的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07Java生態(tài)/Redis中使用Lua腳本的過(guò)程
這篇文章主要介紹了Java生態(tài)/Redis中如何使用Lua腳本,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03安裝多個(gè)版本JDK后使用時(shí)的切換方法總結(jié)
我們平時(shí)在window上做開(kāi)發(fā)的時(shí)候,可能需要同時(shí)開(kāi)發(fā)兩個(gè)甚至多個(gè)項(xiàng)目,有時(shí)不同的項(xiàng)目對(duì)JDK的版本要求有區(qū)別,下面這篇文章主要給大家介紹了安裝多個(gè)版本JDK后使用的切換方法,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-01-01一篇文章弄懂JVM類(lèi)加載機(jī)制過(guò)程以及原理
JVM原理對(duì)于初學(xué)者而言,比較晦澀難以理解,概念繁多又比較抽象,很多時(shí)候感覺(jué)看不見(jiàn)摸不著,還不好驗(yàn)證,下面這篇文章主要給大家介紹了關(guān)于如何通過(guò)一篇文章弄懂JVM類(lèi)加載機(jī)制過(guò)程及原理的相關(guān)資料,需要的朋友可以參考下2023-02-02