日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关联查询---Mybatis学习笔记(九)

發(fā)布時間:2023/12/20 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关联查询---Mybatis学习笔记(九) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

商品訂單數(shù)據(jù)模型

注意:分析數(shù)據(jù)庫表和數(shù)據(jù)庫表之間的關(guān)系可以先通過數(shù)據(jù)庫中的主外鍵關(guān)系來分析,然后通過業(yè)務(wù)中的實際的關(guān)系來分析。

1.一對一查詢

需求:
查詢訂單信息,關(guān)聯(lián)查詢創(chuàng)建訂單的用戶信息

分析需求:
因為一個訂單信息只會是一個人下的訂單,所以從查詢訂單信息出發(fā)關(guān)聯(lián)查詢用戶信息為一對一查詢。如果從用戶信息出發(fā)查詢用戶下的訂單信息則為一對多查詢,因為一個用戶可以下多個訂單。

1.使用ResultType實現(xiàn)

1.sql語句:

select orders.*,user.username,user.birthday,user.sex,user.address from orders,user where orders.user_id = user.id;

2.pojo類:
將上邊的sql語句的查詢結(jié)果映射到pojo中,pojo必須包括所有的查詢列名。
原始的Orders.java不能映射全部的字段,需要新創(chuàng)建一個pojo繼承Order.java類。(一般是繼承包括查詢字段較多的pojo類)

orders類:

public class Orders {private Integer id;private Integer userId;private String number;private Date createtime;private String note;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public Integer getUserId() {return userId;}public void setUserId(Integer userId) {this.userId = userId;}public String getNumber() {return number;}public void setNumber(String number) {this.number = number == null ? null : number.trim();}public Date getCreatetime() {return createtime;}public void setCreatetime(Date createtime) {this.createtime = createtime;}public String getNote() {return note;}public void setNote(String note) {this.note = note == null ? null : note.trim();}@Overridepublic String toString() {return "Orders [id=" + id + ", userId=" + userId + ", number=" + number+ ", createtime=" + createtime + ", note=" + note + "]";}

OrdersCustom.java

public class OrdersCustom extends Orders{private String username;private Date birthday;private String sex;private String address;public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "OrdersCustom [username=" + username + ", birthday=" + birthday + ", sex=" + sex + ", address=" + address+ ", getId()=" + getId() + ", getUserId()=" + getUserId() + ", getNumber()=" + getNumber()+ ", getCreatetime()=" + getCreatetime() + ", getNote()=" + getNote() + "]";}}

3.mapper.xml文件

<mapper namespace="com.huihui.mapper.OrdersCustomMapper"><!-- 查詢訂單關(guān)聯(lián)查詢用戶 --><select id="findOrderUser" resultType="com.huihui.pojo.OrdersCustom">select orders.*,user.username,user.birthday,user.sex,user.address from orders,user where orders.user_id = user.id </select> </mapper>

4.mapper接口:

public interface OrdersCustomMapper {//查詢訂單關(guān)聯(lián)查詢用戶public List<OrdersCustom> findOrderUser() throws Exception; }

5.測試:

public class OrdersCustomMapperTest {private SqlSessionFactory sqlSessionFactory;@Before// 此方法是運(yùn)行下面的測試用例的方法之前執(zhí)行的public void setUp() throws Exception {// 創(chuàng)建sqlSessionFactory// mybatis配置文件路徑String resource = "SqlMapConfig.xml";// 得到配置文件流InputStream inputStream = Resources.getResourceAsStream(resource);// 創(chuàng)建會話工廠,傳入mybatis的配置文件信息sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);}@Testpublic void testFindOrdersUser() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();//創(chuàng)建代理對象OrdersCustomMapper ordersMapperCustom = sqlSession.getMapper(OrdersCustomMapper.class);//調(diào)用mapper的方法List<OrdersCustom> list = ordersMapperCustom.findOrderUser();for (OrdersCustom ordersCustom : list) {System.out.println(ordersCustom);}System.out.println(list.size());sqlSession.close();}}

2.使用ResultMap實現(xiàn)
1.sql語句(同ResultType實現(xiàn)的sql語句一樣):

select orders.*,user.username,user.birthday,user.sex,user.address from orders,user where orders.user_id = user.id;

2.pojo類
使用resultMap將查詢的結(jié)果中的訂單信息映射到Orders對象中,在orders類中添加User屬性,將關(guān)聯(lián)查詢出來的用戶信息映射到Order對象中的user屬性中。
在Orders類中加入User屬性,user屬性中用于存儲關(guān)聯(lián)查詢的用戶信息,因為訂單關(guān)聯(lián)查詢用戶是一對一關(guān)系,所以這里使用單個User對象存儲關(guān)聯(lián)查詢的用戶信息。

Order類:

public class Orders {private Integer id;private Integer userId;private String number;private Date createtime;private String note;//用戶信息private User user;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public Integer getUserId() {return userId;}public void setUserId(Integer userId) {this.userId = userId;}public String getNumber() {return number;}public void setNumber(String number) {this.number = number == null ? null : number.trim();}public Date getCreatetime() {return createtime;}public void setCreatetime(Date createtime) {this.createtime = createtime;}public String getNote() {return note;}public void setNote(String note) {this.note = note == null ? null : note.trim();}public User getUser() {return user;}public void setUser(User user) {this.user = user;}@Overridepublic String toString() {return "Orders [id=" + id + ", userId=" + userId + ", number=" + number+ ", createtime=" + createtime + ", note=" + note + ", user="+ user + "]";}}

3.mapper.xml文件:
定義ResultMap:
需要關(guān)聯(lián)查詢映射的是用戶信息,使用association將用戶信息映射到訂單對象的用戶屬性中。

<!-- 訂單查詢關(guān)聯(lián)用戶的resultmap --><resultMap type="com.huihui.pojo.Orders" id="OrdersUserResultMap"><!-- 配置映射的訂單信息 --><!-- id指定查詢列中的唯一標(biāo)識,如果有多個列組成唯一標(biāo)識,就配置多個id --><!-- column:訂單信息的唯一標(biāo)識列property:訂單信息的唯一標(biāo)識列所映射到的Orders中的那個屬性中--><id column="id" property="id" /><!-- result表示普通列的映射配置 --><result column="user_id" property="userId"/><result column="number" property="number"/><result column="createtime" property="createtime"/><result column="number" property="note"/><!-- 配置映射的關(guān)聯(lián)信息 --><!--association:用于映射關(guān)聯(lián)查詢單個對象的信息 --><!-- property:要將關(guān)聯(lián)查詢的用戶信息映射到Orders中的哪個屬性 javaType:user屬性的java類型--><association property="user" javaType="com.huihui.pojo.User"><!-- id:關(guān)聯(lián)查詢用戶的唯一標(biāo)識 --><!-- column:指定唯一表示用戶信息的列property:映射到user的哪個屬性--><id column="user_id" property="id"/><!-- result:普通列的映射配置 --><result column="username" property="username"/><result column="birthday" property="birthday"/><result column="sex" property="sex"/><result column="address" property="address"/></association></resultMap>

說明:
association:表示進(jìn)行關(guān)聯(lián)查詢單條記錄
property:表示關(guān)聯(lián)查詢的結(jié)果存儲在com.huihui.pojo.Orders的user屬性中
javaType:表示關(guān)聯(lián)查詢的結(jié)果類型
<id property="id" column="user_id"/>:查詢結(jié)果的user_id列對應(yīng)關(guān)聯(lián)對象的id屬性,這里是<id />表示user_id是關(guān)聯(lián)查詢對象的唯一標(biāo)識。
<result property="username" column="username"/>:查詢結(jié)果的username列對應(yīng)關(guān)聯(lián)對象的username屬性。

定義statement:

<!-- 查詢訂單信息關(guān)聯(lián)查詢用戶(使用ResultMap) --><select id="findOrderUserResultMap" resultMap="OrdersUserResultMap">select orders.*,user.username,user.birthday,user.sex,user.address fromorders,user where orders.user_id = user.id</select>

4.mapper接口:

//查詢訂單關(guān)聯(lián)查詢用戶(使用ReusltMap)public List<Orders> findOrderUserResultMap() throws Exception;

5.測試:

@Testpublic void testFindOrdersUserResultMap() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();//創(chuàng)建代理對象OrdersCustomMapper ordersMapperCustom = sqlSession.getMapper(OrdersCustomMapper.class);//調(diào)用mapper的方法List<Orders> list = ordersMapperCustom.findOrderUserResultMap();for (Orders orders : list) {System.out.println(orders);}System.out.println(list.size());sqlSession.close();}

3.resultType和resultMap實現(xiàn)一對一查詢小結(jié):
實現(xiàn)一對一查詢:
定義專門的po類作為輸出類型,其中定義了sql查詢結(jié)果集所有的字段。此方法較為簡單,企業(yè)中使用普遍。

2.一對多查詢

需求:
查詢訂單及訂單明細(xì)的信息。
訂單與訂單明細(xì)為一對多關(guān)系。

分析需求:
查詢的主表:訂單表
查詢的關(guān)聯(lián)表:訂單明細(xì)表
在一對一查詢基礎(chǔ)上添加訂單明細(xì)表關(guān)聯(lián)即可。

使用ResultMap實現(xiàn):

1.sql語句:

SELECTorders.*, USER .username,USER .sex,USER .address,orderdetail.id as orderdetail_id,orderdetail.items_id,orderdetail.items_num,orderdetail.orders_id FROMorders,USER,orderdetail WHEREorders.user_id = USER .id AND orderdetail.orders_id = orders.id;

注意:這里查詢出orderdetail.id as orderdetail_id, 的作用是下面mapper.xml映射文件中的collection標(biāo)簽中需要<id>中的唯一列。

查詢結(jié)果:

發(fā)現(xiàn)結(jié)果中的紅色方框中的記錄是重復(fù)的,但是后邊的items_id、items_num、orders_id列是不重復(fù)的。
那么這里如果使用resultType映射上面的查詢結(jié)果到pojo中的話,那么就會存在重復(fù)的信息。

解決方法:使用resultMap映射,將查詢結(jié)果映射到resultMap中設(shè)置的pojo類中,并且在pojo類中添加List<Orderdetail> orderdetails 屬性。那么最終會將訂單信息映射到orders中,訂單所對應(yīng)的訂單明細(xì)就會映射到orders中的orderdetail屬性中。也就是說上圖中的查詢結(jié)果映射成的orders記錄數(shù)為2條(order信息不重復(fù)),每個orders中的orderdetails屬性存儲了該訂單所對應(yīng)的訂單明細(xì)。

2.pojo類:
Orders.java類中添加如下內(nèi)容:

//訂單明細(xì)private List<Orderdetail> orderdetails;public List<Orderdetail> getOrderdetails() {return orderdetails;}public void setOrderdetails(List<Orderdetail> orderdetails) {this.orderdetails = orderdetails;}

注意還要重寫以下toString()方法,讓toString()方法打印出訂單詳情的信息。

3.mapper.xml映射文件:

定義ResultMap:

<!-- 查詢訂單及訂單明細(xì)的resultmap --><resultMap type="com.huihui.pojo.Orders" id="OrdersAndOrderDetailResultMap"><!-- 訂單信息 --><id column="id" property="id" /><result column="user_id" property="userId" /><result column="number" property="number" /><result column="createtime" property="createtime" /><result column="number" property="note" /><!-- 用戶信息 --><association property="user" javaType="com.huihui.pojo.User"><id column="user_id" property="id" /><result column="username" property="username" /><result column="birthday" property="birthday" /><result column="sex" property="sex" /><result column="address" property="address" /></association><!-- 訂單明細(xì)信息 --><!-- collection:對關(guān)聯(lián)查詢到的多條記錄映射到集合對象中 --><!-- property:將關(guān)聯(lián)查詢到多條記錄映射到com.huihui.pojo.Orders中的哪個屬性ofType:指定映射到集合屬性中pojo的類型--><collection property="orderdetails" ofType="com.huihui.pojo.Orderdetail"><!-- id:訂單明細(xì)的唯一標(biāo)識property:將訂單明細(xì)的唯一標(biāo)識列映射到com.huihui.pojo.Orderdetail中的哪個屬性--><id column="orderdetail_id" property="id"/><result column="items_id" property="itemsId"/><result column="items_num" property="itemsNum"/><result column="orders_id" property="ordersId"/></collection></resultMap>

發(fā)現(xiàn)上面配置中的訂單信息和用戶信息之前在一對一映射(使用ResultMap)中定義ResultMap時定義的相同,那么可以使用繼承(extends)之前定義的ResultMap的方式:

<!-- 查詢訂單及訂單明細(xì)的resultmap --><resultMap type="com.huihui.pojo.Orders" id="OrdersAndOrderDetailResultMap" extends="OrdersUserResultMap"><!-- 訂單信息 --><!-- 用戶信息 --><!-- 訂單明細(xì)信息 --><!-- collection:對關(guān)聯(lián)查詢到的多條記錄映射到集合對象中 --><!-- property:將關(guān)聯(lián)查詢到多條記錄映射到com.huihui.pojo.Orders中的哪個屬性ofType:指定映射到集合屬性中pojo的類型--><collection property="orderdetails" ofType="com.huihui.pojo.Orderdetail"><!-- id:訂單明細(xì)的唯一標(biāo)識property:將訂單明細(xì)的唯一標(biāo)識列映射到com.huihui.pojo.Orderdetail中的哪個屬性--><id column="orderdetail_id" property="id"/><result column="items_id" property="itemsId"/><result column="items_num" property="itemsNum"/><result column="orders_id" property="ordersId"/></collection></resultMap>

說明:
collection部分定義了查詢訂單明細(xì)信息。
collection:表示關(guān)聯(lián)查詢結(jié)果集
property=”orderdetails”:關(guān)聯(lián)查詢的結(jié)果集存儲在com.huihui.pojo.Orders上哪個屬性。
ofType=”com.huihui.pojo.Orderdetail”:指定關(guān)聯(lián)查詢的結(jié)果集中的對象類型即List中的對象類型。
<id />及<result/>的意義同一對一查詢。

定義statement:

<!-- 查詢訂單關(guān)聯(lián)查詢用戶及訂單明細(xì)(使用ResultMap) --><select id="findOrdersAndOrderDetailResultMap" resultMap="OrdersAndOrderDetailResultMap">SELECTorders.*, USER .username,USER .sex,USER .address,orderdetail.id as orderdetail_id,orderdetail.items_id,orderdetail.items_num,orderdetail.orders_idFROMorders,USER,orderdetailWHEREorders.user_id = USER .idANDorderdetail.orders_id = orders.id;</select>

4.mapper接口:

//查詢訂單(關(guān)聯(lián)用戶)及訂單明細(xì)public List<Orders> findOrdersAndOrderDetailResultMap() throws Exception;

5.測試:

@Testpublic void testFindOrdersAndOrderDetailResultMap() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();//創(chuàng)建代理對象OrdersCustomMapper ordersMapperCustom = sqlSession.getMapper(OrdersCustomMapper.class);//調(diào)用mapper的方法List<Orders> list = ordersMapperCustom.findOrdersAndOrderDetailResultMap();for (Orders orders : list) {System.out.println(orders);}System.out.println(list.size());sqlSession.close();}

小結(jié):
mybatis使用resultMap的collection對關(guān)聯(lián)查詢的多條記錄映射到一個list集合屬性中。

如果使用resultType實現(xiàn):
將訂單明細(xì)映射到orders中的orderdetails中,就需要自己手動處理(使用雙重循環(huán)遍歷去去掉重復(fù)記錄,將訂單明細(xì)信息存放到orderdetail中)

3.多對多查詢

需求:
查詢用戶及用戶購買的商品信息

分析需求:
查詢的主表是:用戶表
關(guān)聯(lián)表:由于用戶和商品沒有直接關(guān)聯(lián),通過訂單和訂單明細(xì)進(jìn)行關(guān)聯(lián)。所以關(guān)聯(lián)表為:orders、orderdetail、items

1.sql語句:

SELECTorders.*, USER .username,USER .sex,USER .address,orderdetail.id orderdetail_id,orderdetail.items_id,orderdetail.items_num,orderdetail.orders_id,items. NAME items_name,items.detail items_detail,items.price items_price FROMorders,USER,orderdetail,items WHEREorders.user_id = USER .id AND orderdetail.orders_id = orders.id AND orderdetail.items_id = items.id

2.映射的pojo類:
映射思路:
將用戶信息映射到user中。
在user類中添加訂單列表屬性List<Orders> orderslist,將用戶創(chuàng)建的訂單映射到orderslist。
在Orders中添加訂單明細(xì)列表屬性List<OrderDetail>orderdetials,將訂單的明細(xì)映射到orderdetials。
在OrderDetail中添加Items屬性,將訂單明細(xì)所對應(yīng)的商品映射到Items

User.java類中添加以下內(nèi)容:

private List<Orders> orderslist;//訂單列表public List<Orders> getOrderslist() {return orderslist;}public void setOrderslist(List<Orders> orderslist) {this.orderslist = orderslist;}

Orders.java類中添加以下內(nèi)容:

//訂單明細(xì)private List<Orderdetail> orderdetails;public List<Orderdetail> getOrderdetails() {return orderdetails;}public void setOrderdetails(List<Orderdetail> orderdetails) {this.orderdetails = orderdetails;}

Orderdetail.java類中增加以下內(nèi)容:

private Items items;//訂單明細(xì)所對應(yīng)的商品信息public Items getItems() {return items;}public void setItems(Items items) {this.items = items;}

3.mapper.xml映射文件:
resultmap定義:

<!-- 查詢用戶及購買的商品信息的resultmap --><resultMap type="com.huihui.pojo.User" id="UserAndItemsResultMap"><!-- 用戶信息 --><id column="user_id" property="id"/><result column="username" property="username"/><result column="sex" property="sex"/><result column="address" property="address"/><!-- 訂單信息 --><collection property="orderslist" ofType="com.huihui.pojo.Orders"><id column="id" property="id"/><result column="user_id" property="userId"/><result column="number" property="number"/><result column="createtime" property="createtime"/><result column="note" property="note"/><!-- 訂單明細(xì) --><collection property="orderdetails" ofType="com.huihui.pojo.Orderdetail"><id column="orderdetail_id" property="id"/><result column="items_id" property="ordersId"/><result column="items_num" property="itemsId"/><result column="orders_id" property="itemsNum"/><!-- 商品信息 --><association property="items" javaType="com.huihui.pojo.Items"><id column="items_id" property="id"/><result column="items_name" property="name"/><result column="items_detail" property="detail"/><result column="items_price" property="price"/></association></collection></collection></resultMap>

定義statement:

<!-- 查詢用戶及購買的商品信息,使用resultMap --><select id="findUserAndItemsResultMap" resultMap="UserAndItemsResultMap">SELECTorders.*, USER .username,USER .sex,USER .address,orderdetail.id orderdetail_id,orderdetail.items_id,orderdetail.items_num,orderdetail.orders_id,items. NAME items_name,items.detail items_detail,items.price items_priceFROMorders,USER,orderdetail,itemsWHEREorders.user_id = USER .idAND orderdetail.orders_id = orders.idAND orderdetail.items_id = items.id</select>

4.mapper接口:

//查詢用戶及與用戶相關(guān)聯(lián)的商品信息public List<User> findUserAndItemsResultMap() throws Exception;

5.測試:

@Testpublic void findUserAndItemsResultMap() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();//創(chuàng)建代理對象OrdersCustomMapper ordersMapperCustom = sqlSession.getMapper(OrdersCustomMapper.class);//調(diào)用mapper的方法List<User> list = ordersMapperCustom.findUserAndItemsResultMap();for (User users : list) {System.out.println(users);}System.out.println(list.size());sqlSession.close();}

多對多查詢總結(jié):
將查詢用戶購買的商品信息明細(xì)清單,(用戶名、用戶地址、購買商品名稱、購買商品時間、購買商品數(shù)量)

針對上邊的需求就使用resultType將查詢到的記錄映射到一個擴(kuò)展的pojo中,很簡單實現(xiàn)明細(xì)清單的功能。

一對多是多對多的特例,如下需求:
查詢用戶購買的商品信息,用戶和商品的關(guān)系是多對多關(guān)系。
需求1:
查詢字段:用戶賬號、用戶名稱、用戶性別、商品名稱、商品價格(最常見)
企業(yè)開發(fā)中常見明細(xì)列表,用戶購買商品明細(xì)列表,
使用resultType將上邊查詢列映射到pojo輸出。

需求2:
查詢字段:用戶賬號、用戶名稱、購買商品數(shù)量、商品明細(xì)(鼠標(biāo)移上顯示明細(xì))
使用resultMap將用戶購買的商品明細(xì)列表映射到user對象中。

總結(jié):
使用resultMap是針對那些對查詢結(jié)果映射有特殊要求的功能,,比如特殊要求映射成list中包括 多個list。

ResultMap總結(jié):

resultType:
作用:
將查詢結(jié)果按照sql列名pojo屬性名一致性映射到pojo中。
場合:
常見一些明細(xì)記錄的展示,比如用戶購買商品明細(xì),將關(guān)聯(lián)查詢信息全部展示在頁面時,此時可直接使用resultType將每一條記錄映射到pojo中,在前端頁面遍歷list(list中是pojo)即可。

resultMap:
使用association和collection完成一對一和一對多高級映射(對結(jié)果有特殊的映射要求)。

association:
作用:
將關(guān)聯(lián)查詢信息映射到一個pojo對象中。
場合:
為了方便查詢關(guān)聯(lián)信息可以使用association將關(guān)聯(lián)訂單信息映射為用戶對象的pojo屬性中,比如:查詢訂單及關(guān)聯(lián)用戶信息。
使用resultType無法將查詢結(jié)果映射到pojo對象的pojo屬性中,根據(jù)對結(jié)果集查詢遍歷的需要選擇使用resultType還是resultMap。

collection:
作用:
將關(guān)聯(lián)查詢信息映射到一個list集合中。
場合:
為了方便查詢遍歷關(guān)聯(lián)信息可以使用collection將關(guān)聯(lián)信息映射到list集合中,比如:查詢用戶權(quán)限范圍模塊及模塊下的菜單,可使用collection將模塊映射到模塊list中,將菜單列表映射到模塊對象的菜單list屬性中,這樣的作的目的也是方便對查詢結(jié)果集進(jìn)行遍歷查詢。
如果使用resultType無法將查詢結(jié)果映射到list集合中。

延遲加載

什么是延遲加載?

延遲加載:先從單表查詢、需要時再從關(guān)聯(lián)表去關(guān)聯(lián)查詢,大大提高數(shù)據(jù)庫性能,因為查詢單表要比關(guān)聯(lián)查詢多張表速度要快。

resultMap可以實現(xiàn)高級映射(使用association、collection實現(xiàn)一對一及一對多映射),association、collection具備延遲加載功能。
需求:
如果查詢訂單并且關(guān)聯(lián)查詢用戶信息。如果先查詢訂單信息即可滿足要求,當(dāng)我們需要查詢用戶信息時再查詢用戶信息。把對用戶信息的按需去查詢就是延遲加載。

需求:
查詢訂單并且關(guān)聯(lián)查詢用戶信息

1.pojo類
Orders.java類中增加以下內(nèi)容:

private User user;// 用戶信息public User getUser() {return user;}public void setUser(User user) {this.user = user;}

2.mapper.xml映射文件:

需要定義兩個mapper的方法對應(yīng)的statement。
1、只查詢訂單信息

SELECT * FROM orders

在查詢訂單的statement中使用association去延遲加載(執(zhí)行)下邊的satatement(關(guān)聯(lián)查詢用戶信息)

<!-- 查詢訂單關(guān)聯(lián)查詢用戶信息,用戶信息需要延遲加載 --><select id="findOrdersUserLazyLoading" resultMap="OrdersUserLazyLoadingResultMap">select * from orders</select>

2、關(guān)聯(lián)查詢用戶信息
通過上邊查詢到的訂單信息中user_id去關(guān)聯(lián)查詢用戶信息
使用UserMapper.xml中的findUserById

<select id="findUserById" parameterType="int" resultType="com.huihui.pojo.User">select * from User where id = #{value}</select>

上邊先去執(zhí)行findOrdersUserLazyLoading,當(dāng)需要去查詢用戶的時候再去執(zhí)行findUserById,通過resultMap的定義將延遲加載執(zhí)行配置起來。

3、定義延遲加載的ResultMap
使用association中的select指定延遲加載去執(zhí)行的statement的id。

<!-- 延遲加載用戶信息的resultmap --><resultMap type="com.huihui.pojo.Orders" id="OrdersUserLazyLoadingResultMap"><id column="id" property="id" /><result column="user_id" property="userId" /><result column="number" property="number" /><result column="createtime" property="createtime" /><result column="note" property="note" /><!-- 實現(xiàn)對用戶信息進(jìn)行延遲加載 --><!-- select:指定延遲加載需要執(zhí)行的statement的id(是根據(jù)user_id查詢用戶信息的statement) column:關(guān)聯(lián)查詢的列。訂單信息中關(guān)聯(lián)用戶信息查詢的列,這里是user_id--><association property="user" javaType="com.huihui.pojo.User" select="findUserById" column="user_id"></association></resultMap>

說明:
association:
select=”findUserById”:指定關(guān)聯(lián)查詢sql為findUserById
column=”user_id”:關(guān)聯(lián)查詢時將users_id列的值傳入findUserById
最后將關(guān)聯(lián)查詢結(jié)果映射至com.huihui.pojo.User。

3.mapper接口:

//查詢訂單關(guān)聯(lián)查詢用戶(用戶信息是延遲加載)public List<Orders> findOrdersUserLazyLoading() throws Exception;

3.測試:

執(zhí)行過程:
1、執(zhí)行上邊mapper方法(findOrdersUserLazyLoading),內(nèi)部去調(diào)用com.huihui.mapper.OrdersCustomMapper中的findOrdersUserLazyLoading只查詢orders信息(單表)。
2、在程序中去遍歷上一步驟查詢出的List<Orders>,當(dāng)我們調(diào)用Orders中的getUser方法時,開始進(jìn)行延遲加載。
3、延遲加載,去調(diào)用UserMapper.xml中findUserbyId這個方法獲取用戶信息。

延遲加載配置:
mybatis默認(rèn)沒有開啟延遲加載,需要在SqlMapConfig.xml中setting配置。
在mybatis核心配置文件中配置:lazyLoadingEnabled、aggressiveLazyLoading

設(shè)置項描述允許值默認(rèn)值
lazyLoadingEnabled全局性設(shè)置懶加載。如果設(shè)為‘false’,則所有相關(guān)聯(lián)的都會被初始化加載。true falsefalse
aggressiveLazyLoading當(dāng)設(shè)置為‘true’的時候,懶加載的對象可能被任何懶屬性全部加載。否則,每個屬性都按需加載。true falsetrue

在SqlMapConfig.xml中配置:

<settings><!-- 打開延遲加載的開關(guān) --><setting name="lazyLoadingEnabled" value="true"/><!-- 將積極加載改為消極加載,即按需加載 --><setting name="aggressiveLazyLoading" value="false"/></settings>

測試代碼:

@Testpublic void findOrdersUserLazyLoading() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();//創(chuàng)建代理對象OrdersCustomMapper ordersMapperCustom = sqlSession.getMapper(OrdersCustomMapper.class);//調(diào)用mapper的方法List<Orders> list = ordersMapperCustom.findOrdersUserLazyLoading();//遍歷訂單列表for (Orders orders : list) {//執(zhí)行g(shù)etUser()去查詢用戶信息,這里實現(xiàn)按需加載User user = orders.getUser();System.out.println(user);}sqlSession.close();}

結(jié)果:

延遲加載的思考:
不使用mybatis提供的延遲加載功能是否可以實現(xiàn)延遲加載?
實現(xiàn)方法:
針對訂單和用戶兩個表定義兩個mapper方法。
1、訂單查詢mapper方法
2、根據(jù)用戶id查詢用戶信息mapper方法
默認(rèn)使用訂單查詢mapper方法只查詢訂單信息。
當(dāng)需要關(guān)聯(lián)查詢用戶信息時再調(diào)用根據(jù)用戶id查詢用戶信息mapper方法查詢用戶信息。

延遲加載總結(jié):
作用:
當(dāng)需要查詢關(guān)聯(lián)信息時再去數(shù)據(jù)庫查詢,默認(rèn)不去關(guān)聯(lián)查詢,提高數(shù)據(jù)庫性能。
只有使用resultMap支持延遲加載設(shè)置。
場合:
當(dāng)只有部分記錄需要關(guān)聯(lián)查詢其它信息時,此時可按需延遲加載,需要關(guān)聯(lián)查詢時再向數(shù)據(jù)庫發(fā)出sql,以提高數(shù)據(jù)庫性能。
當(dāng)全部需要關(guān)聯(lián)查詢信息時,此時不用延遲加載,直接將關(guān)聯(lián)查詢信息全部返回即可,可使用resultType或resultMap完成映射。

總結(jié)

以上是生活随笔為你收集整理的关联查询---Mybatis学习笔记(九)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。