1. 程式人生 > >MyBatis學習四 懶載入和快取

MyBatis學習四 懶載入和快取

一.懶載入

mybatis中,resultMap標籤的association標籤和collection標籤具有延遲載入的功能。

resultMap示例配置:

<resultMap type="com.study.first.OrdersExt" id="OrdersAndUserRstMap">
<id column="id" property="id"/>
<result column="user_Id" property="userId"/>
<result column="number" property="number"/>
<!-- 使用者資訊一對一對映 
association:表示一對一對映
        property:表示其要對映的屬性名,
        javaType:表示其對應的java型別
        select:指定關聯查詢的statement,然後將查詢結果封裝到property指定的屬性結果中 -->
<association property="user" javaType="com.study.mpo.User" select="findUserbyId" column="user_Id">
</association>
</resultMap>

查詢user的statement

<select id="findUserbyId" parameterType="int" resultType="com.study.mpo.User">
SELECT *  FROM USER  WHERE user.`id`=#{id}
</select>

查詢語句
<select id="findOrdersAndUserRstMap" resultMap="OrdersAndUserRstMap">
SELECT
*
FROM
orders
</select>

測試;

@Test
	public void test7() throws Exception{
		

		String resource="SqlMapConfig.xml";
		//讀取配置檔案
		InputStream inputStream = Resources.getResourceAsStream(resource);
		//建立sqlsessionFactory
		SqlSessionFactory  sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);
		//建立session
		SqlSession session=sqlSessionFactory.openSession();
		//呼叫session的增刪改查
		OrderExtMapper mapper = session.getMapper(OrderExtMapper.class);
	    System.out.println(mapper.findOrdersAndUserRstMap());
		//提交事物
		session.commit();
		session.close();
	}

二.快取

MyBatis的快取分為一級快取和二級快取,一級快取是sqlSession級別的快取,二級快取指的是同一個namespace下的mapper。一級快取中有個資料區域,就是map結構,key是select語句,statement等資訊組成的,value就是查詢結果的值。二級快取中同樣有

一級快取:

首先,在查詢的時候,會將資料儲存到一級快取中,如果有執行增刪改操作,則會情況以及快取中的資料,再次查詢的時候會將資料再次儲存到以及快取中

sqlMapper.xml

<select id="findUserbyId" parameterType="int" resultType="com.study.mpo.User">
SELECT *  FROM USER  WHERE user.`id`=#{id}
</select>

代理介面方法:

 public User findUserbyId(int id);

測試:

@Test
	public void test10() throws Exception{
		String resource="SqlMapConfig.xml";
		//讀取配置檔案
		InputStream inputStream = Resources.getResourceAsStream(resource);
		//建立sqlsessionFactory
		SqlSessionFactory  sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);
		//建立session
		SqlSession session=sqlSessionFactory.openSession();
		//第一次查詢
		OrderExtMapper mapper1 = session.getMapper(OrderExtMapper.class);
		System.out.println(mapper1.findUserbyId(1));
		//第二次查詢
		OrderExtMapper mapper2 = session.getMapper(OrderExtMapper.class);
		System.out.println(mapper2.findUserbyId(1));
		//提交事物
		session.commit();
		session.close();
	}

結果:

如果進行了增刪改,則會清空一級快取(提交的時候清空),下一次查詢的時候的就會從資料庫查

public void test10() throws Exception{
		String resource="SqlMapConfig.xml";
		//讀取配置檔案
		InputStream inputStream = Resources.getResourceAsStream(resource);
		//建立sqlsessionFactory
		SqlSessionFactory  sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);
		//建立session
		SqlSession session=sqlSessionFactory.openSession();
		//第一次查詢
		OrderExtMapper mapper1 = session.getMapper(OrderExtMapper.class);
		User user=mapper1.findUserbyId(1);
		System.out.println(user);
		user.setId(33);
		mapper1.insertUser(user);
		//提交的時候,就會清空以及快取資訊
		session.commit();
		//第二次查詢
		OrderExtMapper mapper2 = session.getMapper(OrderExtMapper.class);
		System.out.println(mapper2.findUserbyId(1));
		//提交事物
		session.close();
	}

二級快取

sqlMapConfig開啟二級快取,預設就是開啟的

<!--開啟二級快取  -->
<setting name="cacheEnabled" value="true"/>

sqlMap開啟二級快取
<cache/>

使用二級快取要序列化pojo類
public class User implements Serializable {
	private int id;
	private String username;// 使用者姓名
	private String sex;// 性別
	private Date birthday;// 生日
	private String address;// 地址

測試:

@Test
	public void test10() throws Exception{
		String resource="SqlMapConfig.xml";
		//讀取配置檔案
		InputStream inputStream = Resources.getResourceAsStream(resource);
		//建立sqlsessionFactory
		SqlSessionFactory  sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);
		//建立session1
		SqlSession session1=sqlSessionFactory.openSession();
		//建立session2
		SqlSession session2=sqlSessionFactory.openSession();
		//第一次查詢
		OrderExtMapper mapper1 = session1.getMapper(OrderExtMapper.class);
		User user=mapper1.findUserbyId(1);
		System.out.println(user);
		//session關閉時儲存二級快取
        session1.close();
		
		//第二次查詢
		OrderExtMapper mapper2 = session2.getMapper(OrderExtMapper.class);
		System.out.println(mapper2.findUserbyId(1));
        session2.close();
	}

禁用快取

useCache預設是true

<select id="findUserbyId" parameterType="int" resultType="com.study.mpo.User" useCache="false">
SELECT *  FROM USER  WHERE user.`id`=#{id}
</select>

重新整理快取

select語句中預設是false,增刪改中預設是true

<select id="findUserbyId" parameterType="int" resultType="com.study.mpo.User" flushCache="true">
SELECT *  FROM USER  WHERE user.`id`=#{id}
</select>

MyBatis結合Ehcache

新增jar包:

ehcache-core-2.6.5.jar

mybatis-ehcache-1.0.2.jar

配置ehcache.xml檔案

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
	<diskStore path="E:\develop\ehcache" />
	<defaultCache maxElementsInMemory="1000"
	maxElementsOnDisk="10000000" eternal="false" overflowToDisk="false"
	timeToIdleSeconds="120" timeToLiveSeconds="120"
	diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU">
	</defaultCache>
</ehcache>

設定cache的實現類

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