基于mybatis高級(jí)映射多對(duì)多查詢的實(shí)現(xiàn)
1.同以前一樣,首先給一個(gè)使用多對(duì)多的需求,
要查詢用戶以及用戶所購(gòu)買的商品信息,經(jīng)過(guò)分析用戶和商品數(shù)據(jù)庫(kù)級(jí)別沒(méi)有任何關(guān)系,用戶和商品需要建立關(guān)系,要通過(guò)訂單,訂單明細(xì)建立關(guān)系。根據(jù)這個(gè)需求,可以分析出需要查詢的主表為:
查詢主表:用戶表
查詢關(guān)聯(lián)表:由于商品和用戶沒(méi)有關(guān)系,通過(guò)訂單和訂單明細(xì)進(jìn)行關(guān)聯(lián),所以得出關(guān)聯(lián)表是:orders訂單表,orderDetail訂單明細(xì)表,items商品表。這樣的話,sql該如何去寫?這樣寫:
select orders.*, t_user.id user_id, t_user.address, t_user.name, t_user.brithday, orderdetail.id orderdetail_id, orderdetail.orderid, orderdetail.itemsid, items.id items_id, items.name items_name, items.price items_price from orders, t_user, orderdetail, items where orders.userid=t_user.id AND orderdetail.orderid=orders.id AND orderdetail.itemsId = items.id
為了方便映射,適當(dāng)加上別名,上面就是寫好的大sql,這sql語(yǔ)句是越來(lái)越大了,但不要害怕,待會(huì)做映射一個(gè)個(gè)來(lái)做,只要方法得提是很簡(jiǎn)單的。
2.編寫映射文件分析:
現(xiàn)在的主表是user,所以將用戶 的信息映射到user中,一個(gè)用戶可以創(chuàng)建多個(gè)訂單,所以在user屬性中添加List<Orders> orderlist 屬性,這和hibernate越來(lái)越像了哈,然后將用戶創(chuàng)建的訂單映射到orderlist,中一個(gè)訂單可以包括多個(gè)訂單明細(xì),所以在orderS中添加訂單明細(xì)列表屬性:List<OrderDetail> orderdetails ,一個(gè)訂單明細(xì)只包括一個(gè)商品信息,所以在OrderSDetail中添加商品items 屬性。
User.java代碼如下:
public class User { private int id; private String name; private String pwd; private String address; private Date brithday; private List<Orders> ordersList;//看這里 用戶創(chuàng)建的訂單列表 }
Orders.java代碼如下:
public class Orders { private int id; private String note; private Date dateTime; private String number; private int userId; private User user; private List<OrdersDetail> ordersDetails;//一個(gè)訂單包括多個(gè)訂單明細(xì)
OrdersDetail.java代碼如下:
public class OrdersDetail { private int id; private int orderId; private int itemsId; private Items items;//一條訂單明細(xì)包括一條商品信息
到這里,pojo類之間的關(guān)系就搭建好了,接下來(lái)寫mapper.xml
代碼如下(注意看代碼里的注釋):
<!--查詢用戶所購(gòu)買的商品信息resultMap--> <resultMap id="UserAndItemsResultMap" type="com.djp.pojo.User"> <!--配置用戶信息--> <id column="user_id" property="id"/> <result column="address" property="address"/> <result column="name" property="name"/> <result column="brithday" property="brithday"/> <!--配置用戶創(chuàng)建的訂單信息,一個(gè)用戶創(chuàng)建了多個(gè)訂單--> <collection property="ordersList" ofType="com.djp.pojo.Orders"> <id column="id" property="id"/> <result column="note" property="note"/> <result column="dateTime" property="dateTime"/> <result column="userId" property="userId"/> <result column="number" property="number"/> <!--配置訂單明細(xì)信息 一個(gè)訂單包含多個(gè)訂單明細(xì)--> <collection property="ordersDetails" ofType="com.djp.pojo.OrdersDetail"> <id column="orderdetail_id" property="id"/> <result column="orderId" property="orderId"/> <result column="itemsid" property="itemsId"/> <!--配置商品信息 一個(gè)明細(xì)包括一個(gè)商品--> <association property="items" javaType="com.djp.pojo.Items"> <id column="items_id" property="id"/> <result column="items_name" property="name"/> <result column="items_price" property="price"/> </association> </collection> </collection> </resultMap> <!--查詢用戶所購(gòu)買的商品信息--> <select id="findUserAndItemsResultMap" resultMap="UserAndItemsResultMap"> select orders.*, t_user.id user_id, t_user.address, t_user.name, t_user.brithday, orderdetail.id orderdetail_id, orderdetail.orderid, orderdetail.itemsid, items.id items_id, items.name items_name, items.price items_price from orders, t_user, orderdetail, items where orders.userid=t_user.id AND orderdetail.orderid=orders.id AND orderdetail.itemsId = items.id </select>
有了之前一對(duì)多的映射,類比寫這個(gè)就比較簡(jiǎn)單了;這里不能使用繼承,因?yàn)槟惆l(fā)現(xiàn)使用繼承沒(méi)法套用了。所以只能老實(shí)的寫完。
接下來(lái)在接口中添加一個(gè)方法,為查詢用戶所購(gòu)買商品信息
public interface OrdersCustomMapper { /** * 查詢用戶所購(gòu)買的商品 * @return * @throws Exception */ List<User> findUserAndItemsResultMap() throws Exception;
最后一步,寫測(cè)試類:
/**findUserAndItemsResultMap * 查詢用戶所購(gòu)買的商品信息 */ @Test public void testfindUserAndItemsResultMap() { try { System.out.println("start................."); //通過(guò)得到的SqlSessionFactory打開回話sqlSession SqlSession sqlSession = SqlSessionFactory.openSession(); //通過(guò)會(huì)話得到用戶的代理 OrdersCustomMapper ordersCustomMapper = sqlSession.getMapper(OrdersCustomMapper.class); List<User> list = ordersCustomMapper.findUserAndItemsResultMap(); System.out.println("end................."); } catch (Exception e) { e.printStackTrace(); } }
運(yùn)行,結(jié)果如下:
用戶商品.png可以看到我展開的列表,是不是想要的數(shù)據(jù)都出來(lái)了;
總結(jié):
到這里可能有人會(huì)覺(jué)得這個(gè)怎么比hibernate中的多對(duì)多還麻煩,那么,現(xiàn)在如果有這么一個(gè)需求,查詢用戶所購(gòu)買的商品信息明細(xì)清單(用戶名,用戶地址,購(gòu)買商品名稱,購(gòu)買商品時(shí)間,購(gòu)買商品數(shù)量),這個(gè)時(shí)候應(yīng)該使用resultMap還是resulType,這個(gè)時(shí)候會(huì)發(fā)現(xiàn),針對(duì)上面的需求,就是用resultType將查詢到的信息映射到一個(gè)擴(kuò)展的pojo中,很好用,加屬性就行了,這樣的話就可以很簡(jiǎn)單地實(shí)現(xiàn)明細(xì)清單的功能,比如話費(fèi)賬單,張三幾點(diǎn)幾分給誰(shuí)打電話,張三幾點(diǎn)幾分打電話給誰(shuí),沒(méi)必要去重復(fù)記錄。所以,要根據(jù)需求來(lái),并非所有的一對(duì)多都是上面的resultMap那種查詢。使用resultMap是針對(duì)那些查詢結(jié)果有特殊要求的功能,比如映射成list中還包括多個(gè)list。
一對(duì)多是多對(duì)多的特咧:查詢用戶購(gòu)買商品信息,用戶和商品是多對(duì)多關(guān)系。
需求1:查詢字段:用戶賬號(hào),用戶名稱,用戶性別,商品名稱,商品價(jià)格(最常見)。企業(yè)開發(fā)中常見的明細(xì)表,用戶購(gòu)買商品明細(xì)表等。
方法:使用resultType將上面商品輸出
需求2:查詢字段:用戶賬號(hào),用戶名稱,購(gòu)買商品數(shù)量,商品明細(xì)(鼠標(biāo)移動(dòng)到上面顯示明細(xì))
方法:使用resultMap將用戶所購(gòu)買的商品明細(xì)映射到user中。
對(duì)resultMap的大總結(jié):
resultType:
作用:將查詢結(jié)果按照sql列名和pojo屬性名一致映射到pojo中
場(chǎng)合:常見的一些明細(xì)記錄的展示,比如用戶購(gòu)買商品的明細(xì),將關(guān)聯(lián)查詢的信息全部展示在頁(yè)面時(shí),此時(shí)用resultType將每一條記錄映射到pojo中,在前端頁(yè)面遍歷list即可。
resultMap:
使用association和collection完成一對(duì)一和一對(duì)多的高級(jí)映射(對(duì)結(jié)果有特殊要求)。
association:
作用:將關(guān)聯(lián)查詢的信息映射到一個(gè)pojo中
場(chǎng)合:為了方便查詢關(guān)聯(lián)信息可以使用association將關(guān)聯(lián)訂單信息映射為用戶對(duì)象的pojo屬性中,比如:查詢訂單關(guān)聯(lián)查詢用戶信息。
collection:
作用:將關(guān)聯(lián)查詢用戶信息映射到一個(gè)list集合中
場(chǎng)合:為了方便查詢遍歷關(guān)聯(lián)信息可以使用collection將關(guān)聯(lián)信息映射到list集合中,比如:查詢用戶權(quán)限范圍模塊以及模塊下的菜單,可以使用collection將模塊映射到list中,將菜單列表遍歷即可!
以上這篇基于mybatis高級(jí)映射多對(duì)多查詢的實(shí)現(xiàn)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- MyBatis高級(jí)映射學(xué)習(xí)教程
- MyBatis高級(jí)映射和查詢緩存
- Mybatis高級(jí)映射、動(dòng)態(tài)SQL及獲得自增主鍵的解析
- mybatis高級(jí)映射一對(duì)多查詢實(shí)現(xiàn)代碼
- javaMybatis映射屬性,高級(jí)映射詳解
- 解析Mybatis延遲加載問(wèn)題
- MyBatis延遲加載與立即加載案例教程
- MyBatis高級(jí)映射ResultMap解決屬性問(wèn)題
- Mybatis中的延遲加載,以及原理分析
- MyBatis實(shí)現(xiàn)高級(jí)映射的示例代碼
- 詳解MyBatis延遲加載是如何實(shí)現(xiàn)的
- MyBatis高級(jí)映射及延遲加載的實(shí)現(xiàn)
相關(guān)文章
SpringBoot獲取客戶端的IP地址的實(shí)現(xiàn)示例
在Web應(yīng)用程序中,獲取客戶端的IP地址是一項(xiàng)非常常見的需求,本文主要介紹了SpringBoot獲取客戶端的IP地址的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09java代碼獲取數(shù)據(jù)庫(kù)表里數(shù)據(jù)的總數(shù)操作
這篇文章主要介紹了java代碼獲取數(shù)據(jù)庫(kù)表里數(shù)據(jù)的總數(shù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08microlog4android將Android Log日志寫到SD卡文件中實(shí)現(xiàn)方法
這篇文章主要介紹了microlog4android將Android Log日志寫到SD卡文件中實(shí)現(xiàn)方法的相關(guān)資料,需要的朋友可以參考下2016-10-10SpringBoot獲取前臺(tái)參數(shù)的六種方式以及統(tǒng)一響應(yīng)
本文主要介紹了SpringBoot獲取前臺(tái)參數(shù)的六種方式以及統(tǒng)一響應(yīng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03java多線程join()方法的作用和實(shí)現(xiàn)原理解析(應(yīng)用場(chǎng)景)
join方法主要是用于將當(dāng)前線程掛起,等待其他線程結(jié)束后在執(zhí)行當(dāng)前線程,本文通過(guò)應(yīng)用場(chǎng)景分析代碼示例講解java多線程join()方法的作用和實(shí)現(xiàn)原理,感興趣的朋友一起看看吧2021-07-07SpringBoot使用過(guò)濾器、攔截器和監(jiān)聽器的案例代碼(Springboot搭建java項(xiàng)目)
這篇文章主要介紹了SpringBoot使用過(guò)濾器、攔截器和監(jiān)聽器(Springboot搭建java項(xiàng)目),本文是基于Springboot搭建java項(xiàng)目,結(jié)合案例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02