1. 程式人生 > 程式設計 >Mybatis中連線查詢和巢狀查詢例項程式碼

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,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 id="map1" 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 id="findAllPerson" 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 id="map2" 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 id="findAllAddress" 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 id="map3" 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 id="findAllTool" 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 id="map1" 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 id="findPersonFromAddress" resultMap="map1">
  select * from person
 </select>
</mapper>

繼續編寫指向AddressDao介面中的findAddressById:

//按照id查詢Address
List<Address> findAddressById(Integer id);

回到AddressDao配置檔案:

 <mapper namespace="com.fh.dao.AddressDao">
 <!--根據id對address查詢-->
 <select id="findAddressById" resultType="com.fh.domain.Address">
  SELECT * FROM address WHERE aid = #{aid}
 </select>

2、一對多:

AddressDao介面內寫入:

List<Address> findAddressWithPerson();

其對應對映配置中:

<resultMap id="map2" 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 id="findAddressWithPerson" resultMap="map2">
  select * from address
 </select>

針對指出的PersonDao介面的findPersonById:

 List<Person> findPersonById(Integer id);

其對應的對映配置中:

<select id="findPersonById" 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連線查詢和巢狀查詢內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!