mybatis一對(duì)一查詢功能
所謂的一對(duì)一查詢,就是說(shuō)我們?cè)诓樵円粋€(gè)表的數(shù)據(jù)的時(shí)候,需要關(guān)聯(lián)查詢其他表的數(shù)據(jù)。
需求
首先說(shuō)一個(gè)使用一對(duì)一查詢的小需求吧:假設(shè)我們?cè)诓樵兡骋粋€(gè)訂單的信息的時(shí)候,需要關(guān)聯(lián)查詢出創(chuàng)建這個(gè)訂單對(duì)應(yīng)的用戶信息。表模型如下(
ResultType
sql語(yǔ)句的書寫
首先,我們要對(duì)我們的需求進(jìn)行分析。1.我們需要確定這個(gè)需求需要涉及到哪兩張表,其中哪個(gè)是主表,哪個(gè)是關(guān)聯(lián)表。具體怎么確定,還是看需求——我們的需求是說(shuō),在查詢訂單的時(shí)候,順帶著查出創(chuàng)建這個(gè)訂單的用戶。那么,已經(jīng)很顯然了。我們的主表是訂單表(orders)。而我們的關(guān)聯(lián)表則是用戶表(user)。
這個(gè)時(shí)候,我們就可以寫出來(lái)如下sql語(yǔ)句了:
select * from orders
這個(gè)時(shí)候,我們就應(yīng)該考慮這個(gè)問題了:我們?cè)陉P(guān)聯(lián)查詢的時(shí)候應(yīng)該使用內(nèi)鏈接?還是外鏈接?對(duì)于搞不清內(nèi)鏈接外鏈接的區(qū)別的同學(xué),我這里先簡(jiǎn)單的介紹一下,等以后有時(shí)間了,再詳細(xì)寫一篇博客說(shuō)明:內(nèi)連接是只顯示滿足條件的。外鏈接分為左外和右外鏈接:左連接顯示左邊全部的再加上右邊與左邊相同的;右連接顯示右邊全部的和左邊與右邊相同的。
我們的需求是通過訂單去關(guān)聯(lián)用戶,而由于在orders表中有一個(gè)外鍵(userId)。通過外鍵的去查關(guān)聯(lián)表user表的數(shù)據(jù)時(shí),userId是user表的主鍵。這時(shí),只能查到一條user的信息,而這條記錄不會(huì)導(dǎo)致我們的主查詢結(jié)果發(fā)生改變。所以,我們選擇內(nèi)鏈接查詢。這時(shí)候,我們的sql語(yǔ)句是這樣的:
select * from orders,user where orders.user_id = user.id
查詢完成后,出現(xiàn)結(jié)果如下:
這時(shí),問題來(lái)了,我們發(fā)現(xiàn),這個(gè)時(shí)候出現(xiàn)了兩個(gè)id,這就會(huì)導(dǎo)致我們的數(shù)據(jù)在輸出的時(shí)候封裝到對(duì)象時(shí)會(huì)出現(xiàn)問題。而且,User_id 這一列和我們的用戶id數(shù)據(jù)是重復(fù)的。我們需要改造我們的sql。怎么改造呢?
因?yàn)槲覀兊闹鞅頂?shù)據(jù)是要全部查詢的,而用戶表我們只需要username,sex,adress這三個(gè)信息(這里是假設(shè),沒必要糾結(jié)需要的是啥信息)。那么我們就需要手動(dòng)指定我們的sql語(yǔ)句的查詢字段了:
SELECT orders.*, USER.username, USER.sex, USER.address FROM orders, USER WHERE orders.user_id = user.id
前面的這些都是在我們的sql鏈接工具上進(jìn)行查詢的,當(dāng)可以顯示我們需要的數(shù)據(jù)庫(kù)后,我們的sql語(yǔ)句就確定了。這時(shí)我們?cè)撻_始下一步了:
創(chuàng)建pojo
我們需要將查詢到的結(jié)果,通過mybatis框架將數(shù)據(jù)封裝到對(duì)應(yīng)的對(duì)象。那么,問題來(lái)了,這個(gè)查詢到的數(shù)據(jù)由誰(shuí)來(lái)接收?我們?nèi)绻獙⑸线卻ql查詢的結(jié)果映射到pojo中,pojo中必須包括所有查詢列名。但是不管是原來(lái)的Orders類還是User類,都沒有辦法映射全部的字段。這時(shí),我們有一個(gè)很簡(jiǎn)單的解決辦法:根據(jù)返回的字段,專門寫一個(gè)類,讓它包含所有的查詢結(jié)果,然后讓這個(gè)類去接收這個(gè)返回的結(jié)果集。
這時(shí)有個(gè)小技巧,我們的新的pojo中,不需要將所有的字段全部都寫上,我們可以讓新pojo去繼承我們的包含結(jié)果集中查詢字段較多的一個(gè)類,然后將其他需要的數(shù)據(jù)寫到這個(gè)子類中即可。
創(chuàng)建pojo完成后,我們就需要根據(jù)規(guī)范去創(chuàng)建我們的映射文件和寫對(duì)應(yīng)的接口中的方法:
mapper.xml
mapper.java中的接口:
ResultMap
sql語(yǔ)句上,resultType 和resuleMap實(shí)現(xiàn)的方式一樣,這里就直接跳過了。
使用resultMap映射的思路
我們知道,使用pojo的時(shí)候,我們可以將一些數(shù)據(jù)封裝到pojo的對(duì)象屬性中,他的屬性可以是簡(jiǎn)單類型,也可以是另外一個(gè)pojo。這時(shí),我們可以這么做:
使用resultMap將查詢結(jié)果中的訂單信息映射到Orders對(duì)象中,在orders類中添加User屬性,將關(guān)聯(lián)查詢出來(lái)的用戶信息映射到orders對(duì)象中的user屬性中。
Orders類中添加user屬性
mapper.xml
用resultMap的方法將結(jié)果集進(jìn)行映射的時(shí)候,我們需要進(jìn)行兩個(gè)操作,一個(gè)是定義resultMap,設(shè)置每個(gè)查到的結(jié)果集中的列相對(duì)應(yīng)的對(duì)象的屬性。這個(gè)比較麻煩但是不難。二就是定義我們的statement。
resultMap
resultMap實(shí)現(xiàn)的基本思路我們剛才已經(jīng)說(shuō)了。而且也在orders的pojo類中增加了相應(yīng)的屬性了。接下啦,就是寫一個(gè)resultMap,將整個(gè)查詢的結(jié)果映射到Orders中在這里面,首先是order訂單的映射。就是直接用id 和result標(biāo)簽將兩者相互對(duì)應(yīng)即可。然后就是,關(guān)聯(lián)的用戶信息的映射,這時(shí)候需要用到一個(gè)association的標(biāo)簽,將在orders類中的user字段與User類進(jìn)行映射,然后在其內(nèi)部還是用id和result標(biāo)簽,將查詢的數(shù)據(jù)和User的屬性相映射。
具體代碼如下:
<!-- 訂單查詢關(guān)聯(lián)用戶的resultMap 將整個(gè)查詢的結(jié)果映射到cn.mybatis.po.Orders中 --> <resultMap type="cn.mybatis.po.Orders" id="OrdersUserResultMap"> <!-- 配置映射的訂單信息 --> <!-- id:指定查詢列中的唯 一標(biāo)識(shí),訂單信息的中的唯 一標(biāo)識(shí),如果有多個(gè)列組成唯一標(biāo)識(shí),配置多個(gè)id column:訂單信息的唯 一標(biāo)識(shí) 列 property:訂單信息的唯 一標(biāo)識(shí) 列所映射到Orders中哪個(gè)屬性 --> <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/> <!-- 配置映射的關(guān)聯(lián)的用戶信息 --> <!-- association:用于映射關(guān)聯(lián)查詢單個(gè)對(duì)象的信息 property:要將關(guān)聯(lián)查詢的用戶信息映射到Orders中哪個(gè)屬性 --> <association property="user" javaType="cn.mybatis.po.User"> <!-- id:關(guān)聯(lián)查詢用戶的唯 一標(biāo)識(shí) column:指定唯 一標(biāo)識(shí)用戶信息的列 javaType:映射到user的哪個(gè)屬性 --> <id column="user_id" property="id"/> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="address" property="address"/> </association> </resultMap>
statement
statement比較簡(jiǎn)單,就是將返回結(jié)果集的映射方式改成resultMap。然后將返回類型只想我們剛完成的resultMap就可以了。
mapper.java
兩者的區(qū)別
實(shí)現(xiàn)一對(duì)一查詢的方法說(shuō)完了,接下來(lái)分析下它們的不同之處,和優(yōu)劣之處。
首先,都需要對(duì)pojo進(jìn)行修改,一個(gè)是增加一個(gè)pojo類另外一個(gè)則是修改pojo的字段。個(gè)人感覺,根據(jù)設(shè)計(jì)模式中的開閉原則。resultType要比resultMap更好一些。
其次,簡(jiǎn)易程度上來(lái)說(shuō),使用resultType實(shí)現(xiàn)較為簡(jiǎn)單。從這點(diǎn)講,resultType也要比resultMap更好一些。
不過resultMap可以實(shí)現(xiàn)延遲加載,resultType無(wú)法實(shí)現(xiàn)延遲加載。這方面resultType就不如resultMap更好了。
所以:建議大家,如果沒有查詢結(jié)果的特殊要求的話使用resultType。
以上所述是小編給大家介紹的mybatis一對(duì)一查詢功能,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- 關(guān)于mybatis一對(duì)一查詢一對(duì)多查詢遇到的問題
- Mybatis一對(duì)一延遲加載實(shí)現(xiàn)過程解析
- mybatis 一對(duì)一、一對(duì)多和多對(duì)多查詢實(shí)例代碼
- mybatis實(shí)現(xiàn)一對(duì)一關(guān)聯(lián)映射實(shí)例代碼
- Mybatis 中的一對(duì)一,一對(duì)多,多對(duì)多的配置原則示例代碼
- Mybatis中的高級(jí)映射一對(duì)一、一對(duì)多、多對(duì)多
- MyBatis一對(duì)一映射初識(shí)教程
- MyBatis圖文并茂講解注解開發(fā)一對(duì)一查詢
相關(guān)文章
Springmvc自定義類型轉(zhuǎn)換器實(shí)現(xiàn)步驟
這篇文章主要介紹了Springmvc自定義類型轉(zhuǎn)換器實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08springboot與數(shù)據(jù)庫(kù)返回?cái)?shù)據(jù)中文亂碼
大家好,本篇文章主要講的是springboot與數(shù)據(jù)庫(kù)返回?cái)?shù)據(jù)中文亂碼,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2022-01-01Java Socket聊天室編程(一)之利用socket實(shí)現(xiàn)聊天之消息推送
這篇文章主要介紹了Java Socket聊天室編程(一)之利用socket實(shí)現(xiàn)聊天之消息推送的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09WebFlux 服務(wù)編排使用優(yōu)勢(shì)詳解
這篇文章主要為大家介紹了WebFlux 服務(wù)編排使用優(yōu)勢(shì)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05Spring MVC訪問靜態(tài)文件_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了Spring MVC訪問靜態(tài)文件的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08如何解決java中遇到的for input string: "" 報(bào)錯(cuò)問題
在本篇文章里小編給大家整理的是一篇關(guān)于如何解決java中遇到的(for input string: "")報(bào)錯(cuò)內(nèi)容,需要的朋友們可以學(xué)習(xí)下。2020-02-02