MyBatis關(guān)聯(lián)查詢的實(shí)現(xiàn)
前言
在 MyBatis:配置文件 文章中,最后介紹了可以使用 select 標(biāo)簽的 resultMap 屬性實(shí)現(xiàn)關(guān)聯(lián)查詢,下面簡單示例
關(guān)聯(lián)查詢
首先,先創(chuàng)建 association_role 和 association_user 兩張數(shù)據(jù)表,并建立關(guān)聯(lián)關(guān)系
表結(jié)構(gòu)如圖:
表信息如圖:
在創(chuàng)建 association_user 表時(shí)需要添加 association_role 表的關(guān)聯(lián)字段( role_id )
表結(jié)構(gòu)如圖:
表信息如圖:
接著,創(chuàng)建與兩張數(shù)據(jù)表一一映射的實(shí)體類 AssociationRole 和 AssociationUser
// AssociationRole package cn.edu.MyBatisDemo.model; public class AssociationRole { private int id; private String role; public AssociationRole() { super(); } public AssociationRole(int id, String role) { this.id = id; this.role = role; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } @Override public String toString() { return "AssociationRole{" + "id=" + id + ", role='" + role + '\'' + '}'; } }
// AssociationUser package cn.edu.MyBatisDemo.model; public class AssociationUser { private int id; private String name; //添加 AssociationRole 屬性 private AssociationRole role; // AssociationRole -- 1:m -- AssociationUser (一對(duì)多關(guān)系) public AssociationUser(int id, String name, AssociationRole role) { this.id = id; this.name = name; this.role = role; } public AssociationUser() { super(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public AssociationRole getRole() { return role; } public void setRole(AssociationRole role) { this.role = role; } @Override public String toString() { return "AssociationUser{" + "id=" + id + ", name='" + name + '\'' + ", role=" + role + '}'; } }
然后,創(chuàng)建一個(gè)接口 AssociationUserMap ,聲明獲取指定用戶信息的方法。同時(shí),創(chuàng)建映射文件 AssociationUserMap.xml 實(shí)現(xiàn)接口方法
// 接口 AssociationUserMap package cn.edu.MyBatisDemo.mapper; import cn.edu.MyBatisDemo.model.AssociationUser; public interface AssociationUserMap { public AssociationUser selectUserById(int id); // 獲取指定用戶的信息 }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 映射文件 AssociationUserMap.xml --> <mapper namespace="cn.edu.MyBatisDemo.mapper.AssociationUserMap"> <select id="selectUserById" resultMap="associationUser"> SELECT user.id,user.name,user.role_id,role.role FROM association_user USER,`association_role` role WHERE user.role_id=role.id AND user.id=#{id} </select> <!-- id 設(shè)置別名;type 指定類 --> <resultMap id="associationUser" type="cn.edu.MyBatisDemo.model.AssociationUser" > <!-- 字段名對(duì)應(yīng)的屬性名 --> <id column="id" property="id" /> <result column="name" property="name" /> <!-- 映射關(guān)聯(lián)對(duì)象的屬性 --> <result column="role_id" property="role.id" /> <result column="role" property="role.role" /> </resultMap> </mapper>
最后,測(cè)試結(jié)果
package cn.edu.MyBatisDemo.test; import cn.edu.MyBatisDemo.mapper.AssociationUserMap; import cn.edu.MyBatisDemo.model.AssociationUser; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import java.io.IOException; import java.io.InputStream; public class AssociationTest { @Test public void test() throws IOException { //1.根據(jù)配置文件創(chuàng)建數(shù)據(jù)庫連接會(huì)話的工廠類 InputStream inputStream = Resources.getResourceAsStream("mybatis.xml"); //獲取工廠類 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //2.通過工廠類獲取數(shù)據(jù)庫連接的會(huì)話 SqlSession sqlSession = sqlSessionFactory.openSession(); //3.通過 sqlSession 操作數(shù)據(jù)庫 try { AssociationUserMap userMap = sqlSession.getMapper(AssociationUserMap.class); //獲取所有用戶 AssociationUser user = userMap.selectUserById(20230829); System.out.println(user); sqlSession.commit(); } finally { sqlSession.close(); } } }
結(jié)果如圖:
附
懶加載
懶加載( Lazy Loading ),是在使用所需數(shù)據(jù)時(shí)才進(jìn)行加載,而不是直接加載所有關(guān)聯(lián)數(shù)據(jù)。這有利于提高查詢性能和減少資源消耗。當(dāng)一個(gè)實(shí)體類中包含關(guān)聯(lián)對(duì)象(如一對(duì)多、多對(duì)多關(guān)系)時(shí),使用懶加載可以避免在查詢主對(duì)象時(shí)立即加載所有關(guān)聯(lián)對(duì)象的數(shù)據(jù),而是等到真正需要訪問關(guān)聯(lián)對(duì)象時(shí)才進(jìn)行加載。
簡單示例:
在上面案例的基礎(chǔ)上,先通過使用 association 標(biāo)簽實(shí)現(xiàn)分步關(guān)聯(lián)查詢,再進(jìn)行配置懶加載
首先,再創(chuàng)建一個(gè)接口 AssociationRoleMap ,聲明獲取指定用戶信息的方法。同時(shí),創(chuàng)建映射文件 AssociationRoleMap.xml 實(shí)現(xiàn)接口方法
package cn.edu.MyBatisDemo.mapper; import cn.edu.MyBatisDemo.model.AssociationRole; public interface AssociationRoleMap { public AssociationRole selectRoleById(int id); // 獲取指定用戶的信息 }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.edu.MyBatisDemo.mapper.AssociationRoleMap"> <select id="selectRoleById" resultType="associationRole"> SELECT `id`,`role` FROM `association_role` WHERE `id`=#{id} </select> </mapper>
接著,在映射文件 AssociationUserMap.xml 中,使用 association 標(biāo)簽實(shí)現(xiàn)關(guān)聯(lián)查詢。同時(shí),修改 select 標(biāo)簽上的 SQL 語句
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.edu.MyBatisDemo.mapper.AssociationUserMap"> <select id="selectUserById" resultMap="associationUser"> <!-- 對(duì)比:分步關(guān)聯(lián)查詢的 SQL 語句相對(duì)簡單些 --> SELECT `id`,`name`,`role_id` FROM `association_user` WHERE `id`=#{id} </select> <!-- id 設(shè)置別名;type 指定類 --> <resultMap id="associationUser" type="cn.edu.MyBatisDemo.model.AssociationUser" > <!-- 字段名對(duì)應(yīng)的屬性名 --> <id column="id" property="id" /> <result column="name" property="name" /> <!-- 映射關(guān)聯(lián)對(duì)象的屬性 --> <!-- <result column="role_id" property="role.id" /> --> <!-- <result column="role" property="role.role" /> --> <!-- 也可以使用子標(biāo)簽 association 實(shí)現(xiàn)關(guān)聯(lián)查詢 --> <!-- property = 添加 AssociationRole 屬性 role ;select = 關(guān)聯(lián)對(duì)象映射文件中的方法 id ;column = 外鍵 --> <association property="role" select="cn.edu.MyBatisDemo.mapper.AssociationRoleMap.selectRoleById" column="role_id" ></association> </resultMap> </mapper>
然后,在 pom.xml 配置文件中添加依賴包。同時(shí),在 resources 目錄下創(chuàng)建 log4j.properties 資源文件。目的是生成日志文件,方便觀察理解
<!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> </dependency>
#日志級(jí)別,分為八個(gè)級(jí)別( Off-關(guān)閉日志記錄 > Fatal-嚴(yán)重錯(cuò)誤 > Error-錯(cuò)誤 > Warn-警告 > Info-運(yùn)行信息 > Debug-調(diào)試 > Trace-低級(jí)信息 > All-所有日志記錄) #日志級(jí)別越高,過濾的信息越多 #配置根節(jié)點(diǎn) log4j.rootLogger=Debug,stdout,D #配置控制臺(tái)輸出 log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.Threshold=Error ##輸出格式(%d %p [%1] %m %n——日期時(shí)間 類 路徑 信息 換行) log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%l] %m %n #配置文件輸出 log4j.appender.D=org.apache.log4j.DailyRollingFileAppender log4j.appender.D.Append=true log4j.appender.D.File=./log4j.log log4j.appender.D.Threshold=Debug #輸出格式 log4j.appender.D.layout=org.apache.log4j.PatternLayout log4j.appender.D.layout.ConversionPattern=%d %p [%l] %m %n
隨之,在 resources 目錄下的 mybatis.xml 全局配置文件中進(jìn)行配置懶加載
<!-- 懶加載配置 --> <settings> <setting name="LazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings>
最后,測(cè)試結(jié)果
1.只獲取 association_user 中的 name 屬性(只加載所需要的數(shù)據(jù),其他數(shù)據(jù)不加載)
查看日志,結(jié)果如圖:
2.分步關(guān)聯(lián)查詢(加載所有關(guān)聯(lián)數(shù)據(jù))
查看日志,結(jié)果如圖:
對(duì)象為集合時(shí)的關(guān)聯(lián)查詢
當(dāng)關(guān)聯(lián)查詢的對(duì)象為集合時(shí),與上面案例的主要區(qū)別為使用的是 collection 標(biāo)簽,而不是 association 標(biāo)簽。
簡單示例:
首先,在實(shí)體類 AssociationRole 中添加 users 屬性
接著,分別在接口 AssociationUserMap 和 AssociationRoleMap 中添加相應(yīng)的方法
然后,分別在映射文件 AssociationUserMap.xml 和 AssociationRoleMap.xml 中實(shí)現(xiàn)相應(yīng)的方法。同時(shí)在 AssociationRoleMap.xml 配置關(guān)聯(lián)映射
最后,測(cè)試結(jié)果
結(jié)果如圖:
到此這篇關(guān)于MyBatis關(guān)聯(lián)查詢的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)MyBatis關(guān)聯(lián)查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Mybatis-Plus多表關(guān)聯(lián)查詢的使用案例解析
- MyBatis多表關(guān)聯(lián)查詢的實(shí)現(xiàn)示例
- Mybatis表的關(guān)聯(lián)查詢?cè)斍?/a>
- MybatisPlus關(guān)聯(lián)查詢的完美實(shí)現(xiàn)方案
- mybatis-plus多表關(guān)聯(lián)查詢功能的實(shí)現(xiàn)
- Mybatis使用@one和@Many實(shí)現(xiàn)一對(duì)一及一對(duì)多關(guān)聯(lián)查詢
- mybatis如何使用注解實(shí)現(xiàn)一對(duì)多關(guān)聯(lián)查詢
相關(guān)文章
Java基于Dijkstra算法實(shí)現(xiàn)校園導(dǎo)游程序
這篇文章主要為大家詳細(xì)介紹了Java基于Dijkstra算法實(shí)現(xiàn)校園導(dǎo)游程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03IntelliJ IDEA 2018 最新激活碼(截止到2018年1月30日)
這篇文章主要介紹了IntelliJ IDEA 2018 最新激活碼(截止到2018年1月30日)的相關(guān)資料,需要的朋友可以參考下2018-01-01SpringBoot集成Redis—使用RedisRepositories詳解
這篇文章主要介紹了SpringBoot集成Redis—使用RedisRepositories詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03IDEA插件EasyCode及MyBatis最優(yōu)配置步驟詳解
這篇文章主要介紹了IDEA插件EasyCode MyBatis最優(yōu)配置步驟詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12淺談Java中ThreadLocal內(nèi)存泄露的原因及處理方式
內(nèi)存泄漏就是我們申請(qǐng)了內(nèi)存,但是該內(nèi)存一直無法釋放,就會(huì)導(dǎo)致內(nèi)存溢出問題,本文詳細(xì)的介紹了ThreadLocal內(nèi)存泄露的原因及處理方式,感興趣的可以了解一下2023-05-05springboot結(jié)合前端實(shí)現(xiàn)網(wǎng)頁跳轉(zhuǎn)功能實(shí)例
今天處理Springboot統(tǒng)一異常攔截的時(shí)候,遇到了頁面跳轉(zhuǎn)的問題,這篇文章主要給大家介紹了關(guān)于springboot結(jié)合前端實(shí)現(xiàn)網(wǎng)頁跳轉(zhuǎn)功能的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12詳解Spring Cloud Finchley版中Consul多實(shí)例注冊(cè)的問題處理
這篇文章主要介紹了詳解Spring Cloud Finchley版中Consul多實(shí)例注冊(cè)的問題處理,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08Java?GUI實(shí)現(xiàn)多個(gè)窗口切換效果
這篇文章主要為大家詳細(xì)介紹了Java?GUI實(shí)現(xiàn)多個(gè)窗口的切換效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04Maven項(xiàng)目中讀取src/main/resources目錄下的配置文件的方法
本篇文章主要介紹了Maven項(xiàng)目中讀取src/main/resources目錄下的配置文件的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-12-12