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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

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

用戶表user:

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

訂單表:orders

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

訂單明細表:orderdetail:

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

商品表:items

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

表與表之間的業務關系:

???????? 在分析表與表之間的業務關系時需要建立 在某個業務意義基礎上去分析。

先分析數據級別之間有關系的表之間的業務關系:

usre和orders:

  • user---->orders:一個用戶可以創建多個訂單,一對多
  • orders--->user:一個訂單只由一個用戶創建,一對一

orders和orderdetail:

  • orders--->orderdetail:一個訂單可以包括 多個訂單明細,因為一個訂單可以購買多個商品,每個商品的購買信息在orderdetail記錄,一對多關系
  • orderdetail--> orders:一個訂單明細只能包括在一個訂單中,一對一

orderdetail和itesm:

  • orderdetail--->itesms:一個訂單明細只對應一個商品信息,一對一
  • items--> orderdetail:一個商品可以包括在多個訂單明細 ,一對多

再分析數據庫級別沒有關系的表之間是否有業務關系:

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

orders和items之間可以通過orderdetail表建立 關系。

?

高級查詢

1.一對一查詢

1.需求

查詢訂單信息,關聯查詢創建訂單的用戶信息

2.resultType

1.sql語句

  • 確定查詢的主表:訂單表
  • 確定查詢的關聯表:用戶表

???????? 關聯查詢使用內鏈接?還是外鏈接?

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

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

2.創建pojo

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

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

創建 一個pojo繼承包括查詢字段較多的po類。

?

3.mapper.xml

4.mapper.java

3.resultMap

1.sql語句

同resultType實現的sql(同上)

2.使用resultMap映射的思路

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

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

?

4.mapper.xml

定義resultMap

<!-- 訂單查詢關聯用戶的resultMap將整個查詢的結果映射到cn.itcast.mybatis.po.Orders中--><resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap"><!-- 配置映射的訂單信息 --><!-- id:指定查詢列中的唯 一標識,訂單信息的中的唯 一標識,如果有多個列組成唯一標識,配置多個idcolumn:訂單信息的唯 一標識 列property:訂單信息的唯 一標識 列所映射到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/><!-- 配置映射的關聯的用戶信息 --><!-- association:用于映射關聯查詢單個對象的信息property:要將關聯查詢的用戶信息映射到Orders中哪個屬性--><association property="user" javaType="cn.itcast.mybatis.po.User"><!-- id:關聯查詢用戶的唯 一標識column:指定唯 一標識用戶信息的列javaType:映射到user的哪個屬性--><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實現一對一查詢小結

實現一對一查詢:

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

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

resultMap:需要單獨定義resultMap,實現有點麻煩,如果對查詢結果有特殊的要求,使用resultMap可以完成將關聯查詢映射pojo的屬性中。

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

2.一對多查詢

1.需求

查詢訂單及訂單明細的信息。

2.sql語句

  • 確定主查詢表:訂單表
  • 確定關聯查詢表:訂單明細表

在一對一查詢基礎上添加訂單明細表關聯即可。

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將上邊的 查詢結果映射到pojo中,訂單信息的就是重復。

要求:

對orders映射不能出現重復記錄。

?

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

最終會將訂單信息映射到orders中,訂單所對應的訂單明細映射到orders中的orderDetails屬性中。

4.在orders中添加list訂單明細屬性

5.mapper.xml

6.resultMap定義

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

7.mapper.java

8.小結

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

使用resultType實現

將訂單明細映射到orders中的orderdetails中,需要自己處理,使用雙重循環遍歷,去掉重復記錄,將訂單明細放在orderdetails中。

3.多對多查詢

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

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

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

查詢用戶購買的商品信息,用戶和商品的關系是多對多關系。

需求1:

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

企業開發中常見明細列表,用戶購買商品明細列表,

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

?

需求2:

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

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

?

總結:

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

4.resultMap總結

resultType:

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

場合:

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

resultMap:

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

association:

作用:?將關聯查詢信息映射到一個pojo對象中。

場合:

???????? 為了方便查詢關聯信息可以使用association將關聯訂單信息映射為用戶對象的pojo屬性中,比如:查詢訂單及關聯用戶信息。

???????? 使用resultType無法將查詢結果映射到pojo對象的pojo屬性中,根據對結果集查詢遍歷的需要選擇使用resultType還是resultMap。? ? ??

collection:

作用:將關聯查詢信息映射到一個list集合中。

場合:

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

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

查詢緩存

什么是查詢緩存

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

一級緩存是SqlSession級別的緩存。在操作數據庫時需要構造 sqlSession對象,在對象中有一個數據結構(HashMap)用于存儲緩存數據。不同的sqlSession之間的緩存數據區域(HashMap)是互相不影響的。

為什么要用緩存?

如果緩存中有數據就不用從數據庫中獲取,大大提高系統性能。

2.一級緩存

一級緩存工作原理

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

得到用戶信息,將用戶信息存儲到一級緩存中。

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

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

?

一級緩存測試

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

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

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

?

一級緩存應用

正式開發,是將mybatis和spring進行整合開發,事務控制在service中。

一個service方法中包括 很多mapper方法調用。

service{

???????? //開始執行時,開啟事務,創建SqlSession對象

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

????????

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

???????? //方法結束,sqlSession關閉

}

如果是執行兩次service調用查詢相同 的用戶信息,不走一級緩存,因為session方法結束,sqlSession就關閉,一級緩存就清空。

3.二級緩存(了解)

原理

?

?

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

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

每一個namespace的mapper都有一個二緩存區域,兩個mapper的namespace如果相同,這兩個mapper執行sql查詢到數據將存在相同 的二級緩存區域中。

?

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。