1. 程式人生 > >Mybatis延遲載入中有兩個標籤支援延遲載入

Mybatis延遲載入中有兩個標籤支援延遲載入

延遲載入

延遲載入也叫做懶載入lazy

按需要進行載入,是優化查詢速度的方法

Mybatis中有兩個標籤支援延遲載入

<association>

<collection>

操作步驟:

1. 開啟延遲載入開關,關閉積極載入開關

核心配置檔案sqlMapconfig.xml

<settings>

<!-- 開啟延遲載入開關 -->

<setting name="lazyLoadingEnabled" value="true"/>

<!-- 關閉積極載入開關 -->

<setting name="aggressiveLazyLoading" value

="false"/>

</settings>

2. 編寫程式碼

對映檔案:

<resultMap type="cn.itcast.po.Orders" id="orderAndUserLazyResultMap">

<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"/>

<!--

使用延遲載入

select:呼叫要執行的sql語句,使用那個sqlnamespace+.+sql語句的id

例如:cn.itcast.mapper.UserMapper.findUserById

column:是orders表中與user表關聯的欄位

 -->

<association property="user" javaType="cn.itcast.po.User"

select="cn.itcast.mapper.UserMapper.findUserById" column

="user_id">

</association>

</resultMap>

<select id="findOrderAndUserLazy" resultMap="orderAndUserLazyResultMap">

select * from orders

</select>

介面:

public List<Orders> findOrderAndUserLazy();

測試程式碼:

@Test

publicvoid testFindOrderAndUserLazy() throws Exception{

SqlSession openSession = sqlSessionFactory.openSession();

OrdersMapper ordersMapper = openSession.getMapper(OrdersMapper.class);

List<Orders> list = ordersMapper.findOrderAndUserLazy();

for(Orders order : list){

String number = order.getNumber();

System.out.println(number);

User user = order.getUser();

System.out.println(user.getUsername());

}

}

總結

1. 對單個物件的對映關係使用:<association

2. 對集合物件的對映關係使用:<collection

3. 延遲載入:需要在核心配置檔案中配置開關;在mybatisassociationcollection支援延遲載入

快取

優化查詢速度

3.1 一級快取

SqlSession級別的,一級快取由mybatis自己控制,不需要人為干預

1. 第一次查詢會查詢一級快取,如果快取中沒有資料會從資料庫中查詢

2. 如果有更新、刪除、修改操作,那麼會清空快取

3. 接著再次執行查詢則會去資料庫中查詢資料並放到快取中

4. 再次查詢則直接從快取中查詢資料

對映檔案:

<select id="findUserByIdCache1" parameterType="int" resultType="user">

select * from User where id=#{aaa}

</select>

介面:

public User findUserByIdCache1(Integer id);

測試程式碼:

@Test

publicvoid testFindUserByIdCache1() throws Exception{

SqlSession openSession = sqlSessionFactory.openSession();

//獲得Mapper物件

UserMapper userMapper = openSession.getMapper(UserMapper.class);

//第一次查詢

User user1 = userMapper.findUserByIdCache1(1);

System.out.println(user1);

user1.setUsername("李四");

userMapper.updateUserById(user1);

openSession.commit();

//第二次查詢

User user2 = userMapper.findUserByIdCache1(1);

System.out.println(user2);

}

3.2 二級快取

二級快取中的資料可以儲存在記憶體中,或者硬碟中。

操作步驟:

1. 開啟二級快取

SqlMapConfig.xml中加入

<!-- 開啟二級快取 -->

<setting name="cacheEnabled" value="true"/>

2. 在需要二級快取的對映檔案中加入<cache />

UserMapper.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">

<!--

namespace:名稱空間,作用為Sql隔離

 -->

<mapper namespace="cn.itcast.mapper.UserMapper">

<!-- 使用二級快取 -->

<cache />

3. 將查詢的POJO實現Serializable介面

publicclass User implementsSerializable{

privatestaticfinallongserialVersionUID = -6538886943664906447L;

privateintid;

private String username;// 使用者姓名

private String sex;// 性別

private Date birthday;// 生日

private String address;// 地址

對映檔案:

<select id="findUserByIdCache2" parameterType="int" resultType="user">

select * from User where id=#{aaa}

</select>

介面:

public User findUserByIdCache2(Integer id);

測試程式碼:

@Test

publicvoid testFindUserByIdCache2() throws Exception{

SqlSession openSession = sqlSessionFactory.openSession();

//獲得Mapper物件

UserMapper userMapper = openSession.getMapper(UserMapper.class);

//第一次查詢

User user = userMapper.findUserByIdCache2(1);

System.out.println(user);

openSession.close();

//第二次查詢

openSession = sqlSessionFactory.openSession();

userMapper = openSession.getMapper(UserMapper.class);

User user1 = userMapper.findUserByIdCache2(1);

System.out.println(user1);

}

測試程式碼:

@Test

publicvoid testFindUserByIdCache2() throws Exception{

SqlSession openSession = sqlSessionFactory.openSession();

//獲得Mapper物件

UserMapper userMapper = openSession.getMapper(UserMapper.class);

//第一次查詢

User user = userMapper.findUserByIdCache2(1);

System.out.println(user);

openSession.close();

//執行更新操作

openSession = sqlSessionFactory.openSession();

userMapper = openSession.getMapper(UserMapper.class);

user.setUsername("王六");

userMapper.updateUserById(user);

openSession.commit();

openSession.close();

//第二次查詢

openSession = sqlSessionFactory.openSession();

userMapper = openSession.getMapper(UserMapper.class);

User user1 = userMapper.findUserByIdCache2(1);

System.out.println(user1);

openSession.close();

//第三次查詢

openSession = sqlSessionFactory.openSession();

userMapper = openSession.getMapper(UserMapper.class);

User user2 = userMapper.findUserByIdCache2(1);

System.out.println(user2);

openSession.close();

}

3.3 分散式快取

1. 匯入jar

2. 新增ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">

<diskStore path="E:\" />

<!-- maxElementsInMemory記憶體中快取的最大個數 -->

<!-- maxElementsOnDisk硬碟上快取的最大個數 -->

<!-- eternal設定快取中的資料是否永遠不過期 -->

<!-- overflowToDisk設定快取中的資料是否永遠不過期 -->

<!-- overflowToDisk快取資料閒置時間,超過則刪除資料-->

<!-- timeToIdleSeconds快取資料閒置時間,超過則刪除資料-->

<!-- timeToLiveSeconds快取資料存活時間,超過則刪除資料 -->

<!-- diskExpiryThreadIntervalSeconds磁碟快取清理執行緒執行間隔-->

<!-- memoryStoreEvictionPolicy快取策略,最近最少使用,當快取大小到達極限時刪除最近很少使用的-->

<defaultCache 

maxElementsInMemory="1000" 

maxElementsOnDisk="10000000" 

eternal="false" 

overflowToDisk="false" 

timeToIdleSeconds="120"

timeToLiveSeconds="120" 

diskExpiryThreadIntervalSeconds="120"

memoryStoreEvictionPolicy="LRU">

</defaultCache>

</ehcache>

3. 配置對映檔案中使用ehcache實現

<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

4. 測試(同二級快取測試)

flushCache重新整理快取:不配置預設為true

如果配置成false就是永遠不重新整理快取,也就意味著快取中的資料如果更新或者刪除還有新增的時候,就成了髒資料了。

useCache是否使用快取:如果不配置預設為true使用快取。

如果遇到重新整理,更改,刪除操作頻繁的情況下可以設定成false,不適用快取,因為快取的清空還有填充資料,也是需要耗費資源的

3.4 快取的使用:

增加、修改、刪除這樣的操作很少的情況下才能使用快取。

比如電話局的話務系統,話單的查詢功能可以使用快取。