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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

java元婴期(25)----java进阶(mybatis(4)---高级映射查询缓存)

發(fā)布時(shí)間:2025/3/21 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java元婴期(25)----java进阶(mybatis(4)---高级映射查询缓存) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.需要用到的數(shù)據(jù)模型(這是后面高級查詢需要用到的實(shí)例)

用戶表user:

???????? 記錄了購買商品的用戶信息

訂單表:orders

???????? 記錄了用戶所創(chuàng)建的訂單(購買商品的訂單)

訂單明細(xì)表:orderdetail:

???????? 記錄了訂單的詳細(xì)信息即購買商品的信息

商品表:items

???????? 記錄了商品信息

表與表之間的業(yè)務(wù)關(guān)系:

???????? 在分析表與表之間的業(yè)務(wù)關(guān)系時(shí)需要建立 在某個(gè)業(yè)務(wù)意義基礎(chǔ)上去分析。

先分析數(shù)據(jù)級別之間有關(guān)系的表之間的業(yè)務(wù)關(guān)系:

usre和orders:

  • user---->orders:一個(gè)用戶可以創(chuàng)建多個(gè)訂單,一對多
  • orders--->user:一個(gè)訂單只由一個(gè)用戶創(chuàng)建,一對一

orders和orderdetail:

  • orders--->orderdetail:一個(gè)訂單可以包括 多個(gè)訂單明細(xì),因?yàn)橐粋€(gè)訂單可以購買多個(gè)商品,每個(gè)商品的購買信息在orderdetail記錄,一對多關(guān)系
  • orderdetail--> orders:一個(gè)訂單明細(xì)只能包括在一個(gè)訂單中,一對一

orderdetail和itesm:

  • orderdetail--->itesms:一個(gè)訂單明細(xì)只對應(yīng)一個(gè)商品信息,一對一
  • items--> orderdetail:一個(gè)商品可以包括在多個(gè)訂單明細(xì) ,一對多

再分析數(shù)據(jù)庫級別沒有關(guān)系的表之間是否有業(yè)務(wù)關(guān)系:

orders和items:(涉及到數(shù)據(jù)庫的知識)

orders和items之間可以通過orderdetail表建立 關(guān)系。

?

高級查詢

1.一對一查詢

1.需求

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

2.resultType

1.sql語句

  • 確定查詢的主表:訂單表
  • 確定查詢的關(guān)聯(lián)表:用戶表

???????? 關(guān)聯(lián)查詢使用內(nèi)鏈接?還是外鏈接?

???????? 由于orders表中有一個(gè)外鍵(user_id),通過外鍵關(guān)聯(lián)查詢用戶表只能查詢出一條記錄,可以使用內(nèi)鏈接。

SELECT orders.*,USER.username,USER.sex,USER.address FROMorders,USER WHERE orders.user_id = user.id

2.創(chuàng)建pojo

將上邊sql查詢的結(jié)果映射到pojo中,pojo中必須包括所有查詢列名。

原始的Orders.java不能映射全部字段,需要新創(chuàng)建的pojo

創(chuàng)建 一個(gè)pojo繼承包括查詢字段較多的po類。

?

3.mapper.xml

4.mapper.java

3.resultMap

1.sql語句

同resultType實(shí)現(xiàn)的sql(同上)

2.使用resultMap映射的思路

使用resultMap將查詢結(jié)果中的訂單信息映射到Orders對象中,在orders類中添加User屬性,將關(guān)聯(lián)查詢出來的用戶信息映射到orders對象中的user屬性中。

3.需要Orders類中添加user屬性

?

4.mapper.xml

定義resultMap

<!-- 訂單查詢關(guān)聯(lián)用戶的resultMap將整個(gè)查詢的結(jié)果映射到cn.itcast.mybatis.po.Orders中--><resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap"><!-- 配置映射的訂單信息 --><!-- id:指定查詢列中的唯 一標(biāo)識,訂單信息的中的唯 一標(biāo)識,如果有多個(gè)列組成唯一標(biāo)識,配置多個(gè)idcolumn:訂單信息的唯 一標(biāo)識 列property:訂單信息的唯 一標(biāo)識 列所映射到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è)對象的信息property:要將關(guān)聯(lián)查詢的用戶信息映射到Orders中哪個(gè)屬性--><association property="user" javaType="cn.itcast.mybatis.po.User"><!-- id:關(guān)聯(lián)查詢用戶的唯 一標(biāo)識column:指定唯 一標(biāo)識用戶信息的列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定義

5.mapper.java

?

3.resultType和resultMap實(shí)現(xiàn)一對一查詢小結(jié)

實(shí)現(xiàn)一對一查詢:

resultType:使用resultType實(shí)現(xiàn)較為簡單,如果pojo中沒有包括查詢出來的列名,需要增加列名對應(yīng)的屬性,即可完成映射。

如果沒有查詢結(jié)果的特殊要求建議使用resultType

resultMap:需要單獨(dú)定義resultMap,實(shí)現(xiàn)有點(diǎn)麻煩,如果對查詢結(jié)果有特殊的要求,使用resultMap可以完成將關(guān)聯(lián)查詢映射pojo的屬性中。

resultMap可以實(shí)現(xiàn)延遲加載,resultType無法實(shí)現(xiàn)延遲加載。(后面再詳解)

2.一對多查詢

1.需求

查詢訂單及訂單明細(xì)的信息。

2.sql語句

  • 確定主查詢表:訂單表
  • 確定關(guān)聯(lián)查詢表:訂單明細(xì)表

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

SELECTorders.*,USER.username,USER.sex,USER.address,orderdetail.id orderdetail_id,orderdetail.items_id,orderdetail.items_num,orderdetail.orders_idFROMorders,USER,orderdetailWHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id

3.分析

使用resultType將上邊的 查詢結(jié)果映射到pojo中,訂單信息的就是重復(fù)。

要求:

對orders映射不能出現(xiàn)重復(fù)記錄。

?

在orders.java類中添加List<orderDetail> orderDetails屬性。

最終會(huì)將訂單信息映射到orders中,訂單所對應(yīng)的訂單明細(xì)映射到orders中的orderDetails屬性中。

4.在orders中添加list訂單明細(xì)屬性

5.mapper.xml

6.resultMap定義

<!-- 訂單及訂單明細(xì)的resultMap使用extends繼承,不用在中配置訂單信息和用戶信息的映射--><resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersAndOrderDetailResultMap" extends="OrdersUserResultMap"><!-- 訂單信息 --><!-- 用戶信息 --><!-- 使用extends繼承,不用在中配置訂單信息和用戶信息的映射 --><!-- 訂單明細(xì)信息一個(gè)訂單關(guān)聯(lián)查詢出了多條明細(xì),要使用collection進(jìn)行映射collection:對關(guān)聯(lián)查詢到多條記錄映射到集合對象中property:將關(guān)聯(lián)查詢到多條記錄映射到cn.itcast.mybatis.po.Orders哪個(gè)屬性ofType:指定映射到list集合屬性中pojo的類型--><collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"><!-- id:訂單明細(xì)唯 一標(biāo)識property:要將訂單明細(xì)的唯 一標(biāo)識 映射到cn.itcast.mybatis.po.Orderdetail的哪個(gè)屬性--><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>

7.mapper.java

8.小結(jié)

mybatis使用resultMap的collection對關(guān)聯(lián)查詢的多條記錄映射到一個(gè)list集合屬性中。(一對多,推薦使用這種)

使用resultType實(shí)現(xiàn)

將訂單明細(xì)映射到orders中的orderdetails中,需要自己處理,使用雙重循環(huán)遍歷,去掉重復(fù)記錄,將訂單明細(xì)放在orderdetails中。

3.多對多查詢

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

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

一對多是多對多的特例,如下需求:

查詢用戶購買的商品信息,用戶和商品的關(guān)系是多對多關(guān)系。

需求1:

查詢字段:用戶賬號、用戶名稱、用戶性別、商品名稱、商品價(jià)格(最常見)

企業(yè)開發(fā)中常見明細(xì)列表,用戶購買商品明細(xì)列表,

使用resultType將上邊查詢列映射到pojo輸出。

?

需求2:

查詢字段:用戶賬號、用戶名稱、購買商品數(shù)量、商品明細(xì)(鼠標(biāo)移上顯示明細(xì))

使用resultMap將用戶購買的商品明細(xì)列表映射到user對象中。

?

總結(jié):

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

4.resultMap總結(jié)

resultType:

作用:將查詢結(jié)果按照sql列名pojo屬性名一致性映射到pojo中。

場合:

???????? 常見一些明細(xì)記錄的展示,比如用戶購買商品明細(xì),將關(guān)聯(lián)查詢信息全部展示在頁面時(shí),此時(shí)可直接使用resultType將每一條記錄映射到pojo中,在前端頁面遍歷list(list中是pojo)即可。

resultMap:

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

association:

作用:?將關(guān)聯(lián)查詢信息映射到一個(gè)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)查詢信息映射到一個(gè)list集合中。

場合:

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

???????? 如果使用resultType無法將查詢結(jié)果映射到list集合中。

查詢緩存

什么是查詢緩存

  • mybatis提供查詢緩存,用于減輕數(shù)據(jù)壓力,提高數(shù)據(jù)庫性能。
  • mybaits提供一級緩存,和二級緩存。

一級緩存是SqlSession級別的緩存。在操作數(shù)據(jù)庫時(shí)需要構(gòu)造 sqlSession對象,在對象中有一個(gè)數(shù)據(jù)結(jié)構(gòu)(HashMap)用于存儲(chǔ)緩存數(shù)據(jù)。不同的sqlSession之間的緩存數(shù)據(jù)區(qū)域(HashMap)是互相不影響的。

為什么要用緩存?

如果緩存中有數(shù)據(jù)就不用從數(shù)據(jù)庫中獲取,大大提高系統(tǒng)性能。

2.一級緩存

一級緩存工作原理

1.第一次發(fā)起查詢用戶id為1的用戶信息,先去找緩存中是否有id為1的用戶信息,如果沒有,從數(shù)據(jù)庫查詢用戶信息。

得到用戶信息,將用戶信息存儲(chǔ)到一級緩存中。

2.如果sqlSession去執(zhí)行commit操作(執(zhí)行插入、更新、刪除),清空SqlSession中的一級緩存,這樣做的目的為了讓緩存中存儲(chǔ)的是最新的信息,避免臟讀。

3.第二次發(fā)起查詢用戶id為1的用戶信息,先去找緩存中是否有id為1的用戶信息,緩存中有,直接從緩存中獲取用戶信息。

?

一級緩存測試

mybatis默認(rèn)支持一級緩存,不需要在配置文件去配置。

按照上邊一級緩存原理步驟去測試。

@Testpublic void testCache1() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();//創(chuàng)建代理對象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//下邊查詢使用一個(gè)SqlSession//第一次發(fā)起請求,查詢id為1的用戶User user1 = userMapper.findUserById(1);System.out.println(user1);// 如果sqlSession去執(zhí)行commit操作(執(zhí)行插入、更新、刪除),清空SqlSession中的一級緩存,這樣做的目的為了讓緩存中存儲(chǔ)的是最新的信息,避免臟讀。//更新user1的信息user1.setUsername("測試用戶22");userMapper.updateUser(user1);//執(zhí)行commit操作去清空緩存sqlSession.commit();//第二次發(fā)起請求,查詢id為1的用戶User user2 = userMapper.findUserById(1);System.out.println(user2);sqlSession.close();}

?

一級緩存應(yīng)用

正式開發(fā),是將mybatis和spring進(jìn)行整合開發(fā),事務(wù)控制在service中。

一個(gè)service方法中包括 很多mapper方法調(diào)用。

service{

???????? //開始執(zhí)行時(shí),開啟事務(wù),創(chuàng)建SqlSession對象

???????? //第一次調(diào)用mapper的方法findUserById(1)

????????

???????? //第二次調(diào)用mapper的方法findUserById(1),從一級緩存中取數(shù)據(jù)

???????? //方法結(jié)束,sqlSession關(guān)閉

}

如果是執(zhí)行兩次service調(diào)用查詢相同 的用戶信息,不走一級緩存,因?yàn)閟ession方法結(jié)束,sqlSession就關(guān)閉,一級緩存就清空。

3.二級緩存(了解)

原理

?

?

  • 首先開啟mybatis的二級緩存。
  • sqlSession1去查詢用戶id為1的用戶信息,查詢到用戶信息會(huì)將查詢數(shù)據(jù)存儲(chǔ)到二級緩存中。
  • 如果SqlSession3去執(zhí)行相同 mapper下sql,執(zhí)行commit提交,清空該 mapper下的二級緩存區(qū)域的數(shù)據(jù)。
  • sqlSession2去查詢用戶id為1的用戶信息,去緩存中找是否存在數(shù)據(jù),如果存在直接從緩存中取出數(shù)據(jù)。
  • 二級緩存與一級緩存區(qū)別,二級緩存的范圍更大,多個(gè)sqlSession可以共享一個(gè)UserMapper的二級緩存區(qū)域。

UserMapper有一個(gè)二級緩存區(qū)域(按namespace分) ,其它mapper也有自己的二級緩存區(qū)域(按namespace分)。

每一個(gè)namespace的mapper都有一個(gè)二緩存區(qū)域,兩個(gè)mapper的namespace如果相同,這兩個(gè)mapper執(zhí)行sql查詢到數(shù)據(jù)將存在相同 的二級緩存區(qū)域中。

?

總結(jié)

以上是生活随笔為你收集整理的java元婴期(25)----java进阶(mybatis(4)---高级映射查询缓存)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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