Mybatis中連接查詢和嵌套查詢實例代碼
首先在mysql中確立表:
#表一:地址國家表CREATE TABLE address(aid INT AUTO_INCREMENT PRIMARY KEY,aname VARCHAR(20));INSERT INTO address VALUES(NULL,'魏國');INSERT INTO address VALUES(NULL,'蜀國');INSERT INTO address VALUES(NULL,'吳國');#表二:出場人物表CREATE TABLE person(pid INT AUTO_INCREMENT PRIMARY KEY,pname VARCHAR(20),paid INT,CONSTRAINT pafk FOREIGN KEY person(paid) REFERENCES address(aid) ON UPDATE CASCADE ON DELETE CASCADE);INSERT INTO person VALUES(1,'曹操',1);INSERT INTO person VALUES(2,'荀??,1);INSERT INTO person VALUES(3,'張遼',1);INSERT INTO person VALUES(4,'劉備',2);INSERT INTO person VALUES(5,'關羽',2);INSERT INTO person VALUES(6,'張飛',2);INSERT INTO person VALUES(7,'諸葛亮',2);INSERT INTO person VALUES(8,'孫權',3);INSERT INTO person VALUES(9,'周瑜',3);INSERT INTO person VALUES(10,'陸遜',3);INSERT INTO person VALUES(11,'公孫瓚',NULL);#表三:交通工具表CREATE TABLE tool(tid INT AUTO_INCREMENT PRIMARY KEY,tname VARCHAR(20));INSERT INTO tool VALUES(1,'馬');INSERT INTO tool VALUES(2,'船');#表四:地址國家——交通工具 多對多關系表CREATE TABLE aandt(a_aid INT,a_tid INT,PRIMARY KEY(a_aid,a_tid),#聯合主鍵,是指多個字段組成一個組合,該組合在數據表中唯一CONSTRAINT FOREIGN KEY aandt(a_aid) REFERENCES address(aid) ON UPDATE CASCADE ON DELETE CASCADE,CONSTRAINT FOREIGN KEY aandt(a_tid) REFERENCES tool(tid) ON UPDATE CASCADE ON DELETE CASCADE);INSERT INTO aandt VALUES(1,1);INSERT INTO aandt VALUES(2,1);INSERT INTO aandt VALUES(2,2);INSERT INTO aandt VALUES(3,2);
查詢a表的所有信息,如果a表的信息有對應的b表的信息,則查詢b表的信息,如果沒有,則不查詢。
多對一,如:查詢所有人物信息,如果人物有對應國家,則查詢國家信息,如果沒有,則不查詢。多個人物屬于一個國家。
一對多,如:查詢所有國家信息,如果國家有對應人物,則查詢人物信息,如果沒有,則不查詢。一個國家擁有多個城市。
多對多,如:查詢所有國家信息,如果國家擁有對應的交通工具,則查詢交通工具信息,沒有則不查詢。與此同時,多種交通工具存在于于多個國家。
一、連接查詢:連接查詢使用時,使用偏向于a表所在方向的外連接,可獲得a表所有信息,和對應的b表信息。該方式為餓漢式,內存占用較大,但對數據庫訪問次數較少而導致消耗時間少。
1、多對一:<!--多對一的數據庫--> <mapper namespace='com.fh.dao.PersonDao'> <!--該映射的id為map1,該映射的內容為:將查詢到的字段的結果值,按照本映射的對應關系,分別封裝在Person實體類下的各個屬性上,整體構成Person--> <resultMap type='com.fh.domain.Person'> <id column='pid' property='pid'/><!--id:主鍵映射; column:數據庫表字段; property:類中對應屬性名--> <result column='pname' property='pname'/><!--result:非主鍵映射--> <result column='paid' property='paid'/> <association property='address' javaType='com.fh.domain.Address'><!--association:在查詢到多,然后對應出一時,用于關聯對應出一的一方; property:查詢類中包含的子對象屬性; javaType:子對象屬性封裝對應的類--> <id column='aid' property='aid'/> <result column='aname' property='aname'/> </association> </resultMap> <select resultMap='map1'>/*resultMap:自己編寫的結果集,本查詢的返回值正是該結果集所對應的映射組構成的Person*/-- 查詢所有人及其對應的地址,以人為主,則對人側外連接 SELECT * FROM person p LEFT OUTER JOIN address a ON p.paid = a.aid </select></mapper>2、一對多:
<!--一對多的數據庫--> <mapper namespace='com.fh.dao.AddressDao'> <resultMap type='com.fh.domain.Address'> <id column='aid' property='aid'/> <result column='aname' property='aname'/> <collection property='personList' ofType='com.fh.domain.Person'><!--collection:查詢到一,接著關聯對應出多時,指向多的一方; foType:集合中每個元素所屬的映射類--> <id column='pid' property='pid'/> <result column='pname' property='pname'/> <result column='paid' property='paid'/> </collection> </resultMap> <select resultMap='map2'> SELECT * FROM address a LEFT OUTER JOIN person p ON a.aid = p.paid; </select></mapper>3、多對多:
<mapper namespace='com.fh.dao.ToolDao'> <resultMap type='com.fh.domain.Tool'> <id column='tid' property='tid'/> <result column='tname' property='tname'/> <collection property='addressList' ofType='com.fh.domain.Address'> <id column='aid' property='aid'/> <result column='aname' property='aname'/> </collection> </resultMap> <select resultMap='map3'> SELECT t.*,a.* FROM tool AS t LEFT OUTER JOIN aandt AS a_t ON t.`tid` = a_t.`a_tid` LEFT OUTER JOIN address AS a ON a_t.`a_aid` = a.`aid`; </select>二、嵌套查詢:
嵌套查詢使用時,先查詢a表的信息,然后依賴a和b表的外鍵約束,利用in(),再次查詢b表對應到a表上的信息。該方式可以改為餓漢式,內存使用較小,但需要多次訪問數據庫而導致消耗時間多。
1、多對一:PersonDao接口內寫入:
//查詢所有人,以及其對應的地址 List<Person> findPersonFromAddress();
對應映射配置中:
<!--多對一的數據庫--> <mapper namespace='com.fh.dao.PersonDao'> <!--person映射的基本屬性對應下面person的結果集,本結果集內部再繼續進行處理--> <resultMap type='com.fh.domain.Person'> <id column='pid' property='pid'/> <result column='pname' property='pname'/> <result column='paid' property='paid'/> <!-- 對應到person內的子屬性對象,column內為person對應到address的外鍵,由此外鍵,傳入select內的方法進行二次嵌套查詢,交由AddressDao在其中的指定方法進行處理 即要求查詢目標為:Address.aid = Person.paid --> <association property='address' column='paid' select='com.fh.dao.AddressDao.findAddressById'/> </resultMap> <!--第一次查詢為只查詢主要對象,自定義結果集--> <select resultMap='map1'> select * from person </select></mapper>
繼續編寫指向AddressDao接口中的findAddressById:
//按照id查詢AddressList<Address> findAddressById(Integer id);
回到AddressDao配置文件:
<mapper namespace='com.fh.dao.AddressDao'> <!--根據id對address查詢--> <select resultType='com.fh.domain.Address'> SELECT * FROM address WHERE aid = #{aid} </select>2、一對多:
AddressDao接口內寫入:
List<Address> findAddressWithPerson();
其對應映射配置中:
<resultMap type='com.fh.domain.Address'> <id column='aid' property='aid'/> <result column='aname' property='aname'/> <collection property='personList' column='aid' select='com.fh.dao.PersonDao.findPersonById'/> </resultMap> <select resultMap='map2'> select * from address </select>
針對指出的PersonDao接口的findPersonById:
List<Person> findPersonById(Integer id);
其對應的映射配置中:
<select resultType='com.fh.domain.Person'> select * from person where pid = #{pid} </select>
對于嵌套查詢的延遲加載問題,需添加配置:
方法一:
association或collection中多加一條屬性:fetchType=“lazy”
方法二:
<settings> <setting name='lazyLoadingEnable' value='true'/> <setting name='lazyLoadTriggerMethods' value='true'/><!--本條設置表示將包括原本不會延遲加載的equals/clone/hashCode/toString在內所有方法進行延遲加載--> </settings>
到此這篇關于Mybatis中連接查詢和嵌套查詢的文章就介紹到這了,更多相關Mybatis連接查詢和嵌套查詢內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!
相關文章: