文章目錄
- 32.1 MyBatis_延遲加載和立即加載的概念
- 32.2 MyBatis_一對一實作延遲加載
- 32.3 MyBatis_一對多實作延遲加載
- 32.4 MyBatis_緩存的概念
- 32.5 MyBatis_一級緩存
- 32.6 MyBatis_二級緩存:
32.1 MyBatis_延遲加載和立即加載的概念
問題:在一對多中,當我們有一個使用者,它有100個賬戶。
在查詢使用者的時候,要不要把關聯的賬戶查出來?
在查詢賬戶的時候,要不要把關聯的使用者查出來?
在查詢使用者時,使用者下的賬戶資訊應該是,什麼時候使用,什麼時候查詢的。
在查詢賬戶時,賬戶的所屬使用者資訊應該是随着賬戶查詢時一起查詢出來。
- 延遲加載
- 在真正使用資料時才發起查詢,不用的時候不查詢。按需加載(懶加載)
- 立即加載
- 不管用不用,隻要一調用方法,馬上發起查詢。
- 在對應的四種表關系中:一對多,多對一,一對一,多對多
- 一對多,多對多:通常情況下我們都是采用延遲加載。
- 多對一,一對一:通常情況下我們都是采用立即加載。
32.2 MyBatis_一對一實作延遲加載
- IAccountDao.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.dao.IAccountDao">
<!-- 定義封裝account和user的resultMap -->
<resultMap id="accountUserMap" type="account">
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!-- 一對一的關系映射:配置封裝user的内容
select屬性指定的内容:查詢使用者的唯一辨別:
column屬性指定的内容:使用者根據id查詢時,所需要的參數的值
-->
<association property="user" column="uid" javaType="user" select="com.itheima.dao.IUserDao.findById"></association>
</resultMap>
<!-- 查詢所有 -->
<select id="findAll" resultMap="accountUserMap">
select * from account
</select>
</mapper>
- 在主配置檔案中添加标簽,開啟延遲加載
<!--配置參數-->
<settings>
<!--開啟Mybatis支援延遲加載-->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"></setting>
</settings>
32.3 MyBatis_一對多實作延遲加載
- 修改 IUserDao.xml映射檔案
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.dao.IUserDao">
<!-- 定義User的resultMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!-- 配置user對象中accounts集合的映射 -->
<collection property="accounts" ofType="account" select="com.itheima.dao.IAccountDao.findAccountByUid" column="id"></collection>
</resultMap>
<!-- 查詢所有 -->
<select id="findAll" resultMap="userAccountMap">
select * from user
</select>
<!-- 根據id查詢使用者 -->
<select id="findById" parameterType="INT" resultType="user">
select * from user where id = #{uid}
</select>
</mapper>
- 在 IAccountDao中添加一個根據 Id查詢的方法
/**
* 根據id查詢使用者資訊
* @param userId
* @return
*/
User findById(Integer userId);
32.4 MyBatis_緩存的概念
- 什麼是緩存
- 存在于記憶體中的臨時資料
- 為什麼使用緩存
- 減少和資料庫的互動次數,提高執行效率
- 什麼樣的資料能使用緩存,什麼樣的資料不能使用
- 适用于緩存
- 經常查詢并且不經常改變的;
- 資料的正确與否對最終結果影響不大的。
- 不适用于緩存
- 經常改變的資料
- 資料的正确與否對最終結果影響很大的。
- 例如:商品的庫存,銀行的匯率,股市的牌價。
- 适用于緩存
32.5 MyBatis_一級緩存
- 它指的是Mybatis中SqlSession對象的緩存。
- 當我們執行查詢之後,查詢的結果會同時存入到SqlSession為我們提供一塊區域中。
- 該區域的結構是一個Map。當我們再次查詢同樣的資料,mybatis會先去sqlsession中。
- 查詢是否有,有的話直接拿出來用。
- 當SqlSession對象消失時,mybatis的一級緩存也就消失了。
- IUserDao.xml映射檔案如下:
<!-- 根據id查詢使用者 -->
<select id="findById" parameterType="INT" resultType="user">
select * from user where id = #{uid}
</select>
- UserTest.java
/**
* 測試一級緩存
*/
@Test
public void testFirstLevelCache(){
User user1 = userDao.findById(41);
System.out.println(user1);
// sqlSession.close();
//再次擷取SqlSession對象
// sqlSession = factory.openSession();
sqlSession.clearCache();//此方法也可以清空緩存
userDao = sqlSession.getMapper(IUserDao.class);
User user2 = userDao.findById(41);
System.out.println(user2);
System.out.println(user1 == user2);
}
32.6 MyBatis_二級緩存:
- 它指的是Mybatis中SqlSessionFactory對象的緩存。由同一個SqlSessionFactory對象建立的SqlSession共享其緩存。
- 二級緩存的使用步驟:
- 第一步: 讓Mybatis架構支援二級緩存(在SqlMapConfig.xml中配置)
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
- 第二步: 讓目前的映射檔案支援二級緩存(在IUserDao.xml中配置)
<mapper namespace="com.itheima.dao.IUserDao">
<!--開啟user支援二級緩存-->
<cache/>
- 第三步: 讓目前的操作支援二級緩存(在select标簽中配置)
<!-- 根據id查詢使用者 -->
<select id="findById" parameterType="INT" resultType="user" useCache="true">
select * from user where id = #{uid}
</select>