MyBatis缓存二级缓存的使用细节

MyBatis缓存二级缓存的使用细节

缓存原理图展示


<?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.cn.mybatis.dao.EmployeeMapper">
  	<cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"> </cache>
  	<!-- 
  	   eviction : 缓存的回收策略
  	         LRU 最近最少使用的, 移除最长时间不被使用的对象。
  	         FIFO 先进先出,按对象进入缓存的顺序来移除他们。
  	         SOFT 软引用,移除基于垃圾回收器和软引用规则的对象
  	         WEAK 弱引用,更积极的移除基于垃圾收集器状态和弱引用规则的对象
  	         默认的是lRU
  	         
  	         flushInterval 缓存刷新间隔
  	            缓存多长时间清空一次,默认不清空,设置一个毫秒值
  	        readOnly : 是否只读
  	           true 只读   mybatis认为所有从缓存中获取数据的操作都是只读操作 ,不会修改数据。
  	           			mybatis 为了加快获取速度,直接就会将数据在缓存中的引用交给用户
  	           false 非只读  mybatis觉得 获取的数据可能会被修改。
  	                 mybatis会利用序列化   反序列化的技术克隆一份新的数据给你
  	        size: 缓存存放多少元素
  	        type="" 指定自定义缓存的全类名
  	                         实现chche接口即可
  	        
  	 -->

</mapper>


package com.cn.zhu.mybatis.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import com.cn.mybatis.dao.EmployeeMapper;
import com.cn.mybatis.dao.EmployeeMapperDynamicSQL;
import com.cn.zhu.bean.Department;
import com.cn.zhu.bean.Employee;
import com.sun.org.apache.bcel.internal.classfile.Deprecated;

/**
 * 1 接口式编程
 *   原生       dao  ====>  DaoImpI
 *   mybatis  Mapper====>xxMapper.xml
 *   
 * 2 Sql Session 代表 和数据库的一次回话,用完必须关闭
 * 3 SqlSession 和  connection 一样她都是非线程安全。
 * @author Administrator
 *
 */
public class MyBatisTest {
	public SqlSessionFactory getSqlSessionFactory() throws IOException{
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		return  new SqlSessionFactoryBuilder().build(inputStream);
	}
	/**
	 * 两级缓存
	 * 一级缓存:(本地缓存) sqlsession级别的缓存,一级缓存是一直开启的。
	 *      与数据库同一次回话期间查询到的数据库会放在本地缓存中
	 *      以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库
	 *      
	 *      一级缓存失效情况  (没有使用到当前一级缓存的情况,效果就是,还需要再向数据库发出查询)
	 *      1. sqlsession不同
	 *      2  sqlsession相同,查询条件(当前缓存中,有这个数据)
	 *      3. sqlSession相同,两次查询之间执行了增删改操作(这次增删改查对当前数据库有影响)
	 *      4  sqlSession相同,手动清除了一级缓存(缓存清空)
	 * 二级缓存: (全局缓存) 基于namespace级别的缓存  一个namespace对应一个二级缓存
	 *     工作机制:
	 *       1. 一个会话,查询一条数据,这个数据就会被放在当前回话的一级缓存中
	 *       2 如果会被关闭,一级缓存中的数据会被保存到二级缓存中,新的会话查询信息,就可以
	 *       参照二级缓存中的内容
	 *       3 sqlSession===EmployeeMapper==>Employee
	 *       		   DepartmentMapper===Department
	 *           不同namespace 查出的数据会放在自己对应的缓存中(maP)
	 *           效果   数据会从二级缓存中获取,
	 *                查出的数据都会被默认先放在一级缓存中
	 *                只有会话提交或者关闭后,一级缓存中的数据才会转移到二级缓存中
	 * 
	 *     使用:
	 *        1. 开启全局二级缓存配置,<setting name="cacheEnabled" value="true"/>
	 * @throws IOException 
	 */
/*	@Test
	public void testFirstLevelCache() throws IOException{
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
		SqlSession openSession = sqlSessionFactory.openSession();
		try{
			EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
			Employee emp1 = mapper.getEmpById(1);
			System.out.println(emp1);
			
			// 1. sqlsesion不同
			//SqlSession openSession2 = sqlSessionFactory.openSession();
			//EmployeeMapper mapper2 = openSession2.getMapper(EmployeeMapper.class);
		
			// sqlsession相同,查询条件
			Employee emp2 = mapper.getEmpById(1);
			System.out.println(emp2);
			System.out.println(emp1==emp2);
			
			//openSession2.close();
		}finally{
			openSession.close();
		}
	}*/
	@Test
	public void testSecondLevelCache() throws IOException{
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
		SqlSession openSession = sqlSessionFactory.openSession();
		SqlSession openSession2= sqlSessionFactory.openSession();
		try{
			EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
			EmployeeMapper mapper2 = openSession2.getMapper(EmployeeMapper.class);
			Employee emp = mapper.getEmpById(1);
			System.out.println(emp);
			openSession.close();
			//第二次查询是从二级缓存中拿到的数据,并没有发送新的sql
			Employee emp2 = mapper2.getEmpById(1);
			System.out.println(emp2);
			openSession2.close();
		}finally{
			
		}
	}
}

 数据会从二级缓存中获取,
	 *                查出的数据都会被默认先放在一级缓存中
	 *                只有会话提交或者关闭后,一级缓存中的数据才会转移到二级缓存中


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值