MyBatis中一對多的xml配置方式(嵌套查詢/嵌套結(jié)果)
MyBatis一對多的xml配置
用的是window上面的畫圖板,沒法以文字的方式展示出來,見諒
嵌套查詢
嵌套結(jié)果
一對多關(guān)聯(lián)查詢xml配置寫法
情景概述
1、有一張客戶表 Client ,存儲(chǔ)客戶信息, 姓名 name ,年齡 age等。
2、有一張客戶附件表 client_file ,存儲(chǔ)客戶附件信息,附件名 name ,路徑 path 等,其中通過外鍵 client_id 關(guān)聯(lián)到 client表,獲取附件對應(yīng)的客戶信息。
3、需求如下:
- 查詢某個(gè)客戶時(shí),獲取客戶名下的所有附件信息。 (一對多查詢)
- 查詢某個(gè)附件時(shí),獲取附件所屬的客戶信息。 (一對一 查詢)
創(chuàng)建表
1、創(chuàng)建 client 表,并插入數(shù)據(jù)
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for client -- ---------------------------- DROP TABLE IF EXISTS `client`; CREATE TABLE `client` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '編號(hào)', `name` varchar(255) DEFAULT NULL COMMENT '姓名', `age` int(255) DEFAULT NULL COMMENT '年齡', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of client -- ---------------------------- INSERT INTO `client` VALUES ('1', '小明', '18'); INSERT INTO `client` VALUES ('2', '小紅', '22'); INSERT INTO `client` VALUES ('3', '小剛', '27');
2、創(chuàng)建 client_file 表,并插入數(shù)據(jù)
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for client_file -- ---------------------------- DROP TABLE IF EXISTS `client_file`; CREATE TABLE `client_file` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '編號(hào)', `name` varchar(255) DEFAULT NULL COMMENT '附件名', `path` varchar(255) DEFAULT NULL COMMENT '附件路徑', `client_id` int(11) DEFAULT NULL COMMENT '客戶id', PRIMARY KEY (`id`), KEY `client_id` (`client_id`), CONSTRAINT `client_id` FOREIGN KEY (`client_id`) REFERENCES `client` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of client_file -- ---------------------------- INSERT INTO `client_file` VALUES ('1', '小明電影', '/usr/local/子彈飛.mp4', '1'); INSERT INTO `client_file` VALUES ('2', '小明簡歷', '/usr/doc/小明.docx', '1'); INSERT INTO `client_file` VALUES ('3', '小明代碼', '/usr/code/main.java', '1'); INSERT INTO `client_file` VALUES ('4', '小紅靚照', 'E:\\image\\xiaohong.jpg', '2');
3、關(guān)系如下:
對應(yīng) java Pojo
1、client表對應(yīng) Client.java
public class Client2 implements Serializable { private static final long serialVersionUID = 1L; private String id; private String name; // 姓名 private String age; // 年齡 private List<ClientFile> clientFileList ; // 客戶名下的附件 list // ======= ignore getter,setter ========= // }
2、client_file表對應(yīng) ClientFile.java
public class ClientFile implements Serializable { private static final long serialVersionUID = 1L; private String id; private String path; // 附件路徑 private String clientId; // 客戶id private Client clientInfo ; // 客戶信息 // ======= ignore getter,setter ========= // }
查詢 客戶表client 獲取客戶名下的附件信息
1、方法一: 使用一個(gè)結(jié)果集實(shí)現(xiàn)獲取client表客戶關(guān)聯(lián)的附件信息(錯(cuò)誤方法)
1.1、 resultMap 定義:
<resultMap type="Client" id="clientMapError"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> <collection property="clientFileList" ofType="ClientFile"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="path" column="path"/> <result property="clientId" column="client_id"/> </collection> </resultMap>
1.2、SQL查詢代碼:
<select id="getMapError" resultMap="clientMapError" parameterType="Client"> SELECT a.id , a.name , a.age , cf.id, cf.name , cf.path , cf.client_id FROM client a LEFT JOIN client_file cf on cf.client_id = a.id WHERE a.id = #{id} </select>
1.3、測試:獲取客戶 id=1的客戶名下附件,查詢結(jié)果如下JSON:
1.4、原因分析:通過查看client_file表,client_id=1,對應(yīng)有3個(gè)附件,而本次查詢中只查到了一個(gè)附件,且client_file表中id=1的name值為"小明電影"??梢钥吹?client表和client_file表中有共同字段id,name 在映射的時(shí)候?qū)lient表中數(shù)據(jù)映射到 client_file表中去了,解決這一問題,需要將 client_file表中重名字段做別名處理。
2、方法一: 使用一個(gè)結(jié)果集實(shí)現(xiàn)獲取client表客戶關(guān)聯(lián)的附件信息。(重名字段做別名處理)
2.1、 resultMap 定義:
<resultMap type="Client" id="clientMap"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> <collection property="clientFileList" ofType="ClientFile"> <id property="id" column="fileId"/> <result property="name" column="fileName"/> <result property="path" column="path"/> <result property="clientId" column="client_id"/> </collection> </resultMap>
2.2、SQL 查詢代碼:
<select id="getMap" resultMap="clientMap" parameterType="Client"> SELECT a.id , a.name , a.age , cf.id AS "fileId", cf.name AS "fileName" , cf.path , cf.client_id FROM client a LEFT JOIN client_file cf on cf.client_id = a.id WHERE a.id = #{id} </select>
2.3、測試:獲取客戶 id=1 的客戶名下附件,查詢結(jié)果如下JSON:
3、方法二:使用多個(gè)結(jié)果集實(shí)現(xiàn)獲取client表客戶關(guān)聯(lián)的附件信息。(重名字段不做別名處理)
3.1、resultMap 定義:
<resultMap type="Client" id="clientMap2"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> <!-- column: 對應(yīng)的外鍵。 client表的id是client_file表的 外鍵 --> <collection property="clientFileList" ofType="ClientFile" column="id" select="getClientFileList"></collection> </resultMap>
3.2、SQL查詢代碼:
<select id="getMap2" resultMap="clientMap2" parameterType="Client"> SELECT a.id , a.name , a.age FROM client a WHERE id = #{id} </select> <select id="getClientFileList" resultType="ClientFile" parameterType="int"> SELECT b.id , b.name , b.path , b.client_id FROM client_file b WHERE client_id = #{id} </select>
3.3、獲取客戶 id=2 的客戶名下附件,查詢結(jié)果如下JSON:
查詢 客戶附件表 client_file 獲取附件所屬的客戶信息
1、方法一:使用一個(gè)結(jié)果集實(shí)現(xiàn)獲取client_file表所屬的客戶信息(錯(cuò)誤方法)
1.1、resultMap 定義:
<resultMap type="ClientFile" id="clientFileMapError"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="path" column="path"/> <result property="clientId" column="client_id"/> <association property="clientInfo" javaType="Client"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> </association> </resultMap>
1.2、SQL查詢代碼:
<select id="getMapError" resultMap="clientFileMapError" parameterType="ClientFile"> SELECT cf.id , cf.name , cf.path ,cf.client_id , a.id , a.name , age FROM client_file cf LEFT JOIN client a on a.id = cf.client_id WHERE cf.id = #{id} </select>
1.3、測試:獲取附件表 id=3 的附件所屬客戶信息,查詢結(jié)果如下JSON:
1.4、原因分析:通過查看client_file表id=3,對應(yīng)client_id為1,而查詢到的clientInfo對象中id=3,name="小明代碼",這里和client表中的數(shù)據(jù)不對,原因同上----字段對應(yīng)屬性值映射錯(cuò)誤。解決這個(gè)問題,需要將重名字段進(jìn)行別名處理。
2、方法一:使用一個(gè)結(jié)果集實(shí)現(xiàn)獲取client_file表所屬的客戶信息。(重名字段別名處理)
2.1、resultMap 定義:
<resultMap type="ClientFile" id="clientFileMap"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="path" column="path"/> <result property="clientId" column="client_id"/> <association property="clientInfo" javaType="Client"> <id property="id" column="c_id"/> <result property="name" column="clientName"/> <result property="age" column="age"/> </association> </resultMap>
2.2、SQL查詢代碼:
<select id="getMap" resultMap="clientFileMap" parameterType="ClientFile"> SELECT cf.id , cf.name , cf.path ,cf.client_id , a.id AS "c_id" , a.name AS "clientName", age FROM client_file cf LEFT JOIN client a on a.id = cf.client_id WHERE cf.id= #{id} </select>
2.3、測試:獲取附件表 id=2 的附件所屬客戶信息,查詢結(jié)果如下JSON:
3、方法二:使用多個(gè)結(jié)果集實(shí)現(xiàn)獲取client_file表所屬的客戶信息(重名字段不處理)
3.1、resultMap 定義:
<resultMap type="ClientFile" id="clientFileMap2"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="path" column="path"/> <result property="clientId" column="client_id"/> <association property="clientInfo" column="client_id" select="getClientInfo"></association> </resultMap>
3.2、SQL查詢代碼:
<select id="getMap2" resultMap="clientFileMap2" parameterType="ClientFile"> SELECT cf.id , cf.name , cf.path ,cf.client_id FROM client_file cf WHERE cf.id= #{id} </select> <select id="getClientInfo" resultType="Client" parameterType="int"> SELECT id , name ,age FROM client WHERE id = #{id} </select>
3.3、獲取附件表 id=4 的附件所屬客戶信息,查詢結(jié)果如下JSON:
小結(jié)一下
1、MyBatis中一對多關(guān)聯(lián)查詢使用 <collection> 標(biāo)簽來實(shí)現(xiàn)關(guān)聯(lián),主要屬性作用如下:
property
:java對象名稱ofType
:java對象的類型column
:當(dāng)前表對應(yīng)的外鍵字段名稱select
:另一個(gè)數(shù)據(jù)集的名稱
2、MyBatis中一對一關(guān)聯(lián)查詢使用 <association> 標(biāo)簽來實(shí)現(xiàn)關(guān)聯(lián),主要屬性作用如下:
property
:java對象名稱javaType
:java對象類型colmun
:當(dāng)前表對應(yīng)的外鍵字段名稱seelct
:另一個(gè)數(shù)據(jù)集的名稱
3、使用一個(gè)數(shù)據(jù)集時(shí),注意關(guān)聯(lián)表之間的字段是否有重名情況,若有重名,需要?jiǎng)e名處理。
4、使用多個(gè)數(shù)據(jù)集時(shí),無需關(guān)注字段重名情況。
5、一個(gè) resultMap標(biāo)簽可以配置多個(gè)<collection>標(biāo)簽和<association>標(biāo)簽。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Boot與Spring Security的跨域問題解決方案
跨域問題是指在Web開發(fā)中,瀏覽器出于安全考慮,限制了不同域名之間的資源訪問,本文重點(diǎn)給大家介紹Spring Boot與Spring Security的跨域問題解決方案,感興趣的朋友一起看看吧2023-09-09java 用遞歸獲取一個(gè)目錄下的所有文件路徑的小例子
還是日志的問題,log4j生成的日志文件,自動(dòng)保存到月份所在的文件夾中,需要獲取到所有的日志文件,包括文件夾2013-09-09Spring+MyBatis實(shí)現(xiàn)數(shù)據(jù)讀寫分離的實(shí)例代碼
本篇文章主要介紹了Spring+MyBatis實(shí)現(xiàn)數(shù)據(jù)讀寫分離的實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07Spring實(shí)現(xiàn)IoC的多種方式小結(jié)
本篇文章主要介紹了Spring實(shí)現(xiàn)IoC的多種方式小結(jié),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02