MyBatis框架数据缓存

MyBatis缓存介绍:

1.MyBatis提供缓存机制分别有sqlseeion缓存(一级缓存)和sqlsessionFactory缓存(二级缓存);

2.二者区别在于作用域不一样;

3.缓冲区更新机制,当作用域(sqlseeion缓存/sqlsessionFactory缓存)进行  增/删/改 的时候,对应的作用域缓存会被清除;

一级缓存测试:

同一个sqlseeion 执行同一个select标签(调用SQL)时,第一次调用select标签会去数据库将数据缓存到缓冲区中并且返回数据结果,第二调用select标签是在缓冲区中获得数据结果,不同的sqlseeion 不共用缓存;

package com.gx.servlet;

import java.io.IOException;
import java.io.InputStream;
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 com.gx.dao.cacheMapper;
import com.gx.pojo.Account;

public class 缓存 {
	public static void main(String[] args) throws IOException {
		
		//数据库连接属性
		InputStream resourceAsStream = Resources.getResourceAsStream("GlobalConfiguration.xml");
		SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
		
		//作用域One
		SqlSession openSessionOne = build.openSession();
		//作用域Two
		SqlSession openSessionTwo = build.openSession();
		
		//作用域One----第一次调用selAll需要访问数据库
		cacheMapper mapperOne = openSessionOne.getMapper(cacheMapper.class);
		List<Account> selAllOne = mapperOne.selAll();
		for (Account account : selAllOne) {
			System.out.println("我是数据库的数据:"+account.toString());
		}
		//作用域One----第二次selAll调用直接调用缓存
		System.out.println("第二次运行不需要去访问数据库");
		cacheMapper mapperOne1 = openSessionOne.getMapper(cacheMapper.class);
		List<Account> selAllOne1 = mapperOne1.selAll();
		for (Account account : selAllOne1) {
			System.out.println("我是缓冲区的数据:"+account.toString());
		}
		//作用域Two----同样调用selAll,但不是同一个SqlSession作用域,所以要重新访问数据库
		cacheMapper mapper1 = openSessionTwo.getMapper(cacheMapper.class);
		List<Account> selAll1 = mapper1.selAll();
		for (Account account : selAll1) {
			System.out.println(account.toString());
		}
		
	}
}

运行结果:

可以从运行结果中看到执行了两次查询sql语句,第二次不需要执行查询sql语句;

因为有缓存机制,可以大大降低对数据库的访问,都知道访问数据库是比较耗时的,这样不用重复访问数据库可以大大提升速度;

二级缓存测试:

sqlsessionFactory下的两个不相同的sqlseeion执行同一个select标签(调用SQL)时,也可以使用缓存的数据数据,如第一次调用需要去数据库访问,第二次就直接调用缓存;

开启二级缓存有两种方法:

第一种:加入cache 标签,并且设置读取属性

<?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.gx.dao.cacheMapper">
<!--开启二级缓存-->
  <cache readOnly="true"></cache>

  <select id="selAll" resultType="Account">
  select * from Account
  </select>
  </mapper>

第二种:加入cache 标签,不加只读属性;但操作的类必须系列化,如 class Account implements Serializable{}

二级缓存测试:

package com.gx.servlet;

import java.io.IOException;
import java.io.InputStream;
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 com.gx.dao.cacheMapper;
import com.gx.pojo.Account;

public class 缓存 {
	public static void main(String[] args) throws IOException {
		
		//数据库连接属性
		InputStream resourceAsStream = Resources.getResourceAsStream("GlobalConfiguration.xml");
		SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
		
		//作用域One
		SqlSession openSessionOne = build.openSession();
		//作用域Two
		SqlSession openSessionTwo = build.openSession();
		
		//作用域One
		cacheMapper mapperOne = openSessionOne.getMapper(cacheMapper.class);
		List<Account> selAllOne = mapperOne.selAll();
		for (Account account : selAllOne) {
			System.out.println("我是数据库的数据:"+account.toString());
		}
		//必须关闭或者提交数据才会缓冲到缓冲区中
  		openSessionOne.close();
                //openSessionOne.commit()

		//作用域Two
		cacheMapper mapperTwo = openSessionTwo.getMapper(cacheMapper.class);
		List<Account> selAllTwo = mapperTwo.selAll();
		for (Account account : selAllTwo) {
			System.out.println(account.toString());
		}
		openSessionOne.close();
	}
}

运行结果:

只执行了一次查询SQL语句,第二次获取缓存的数据不需要调用SQL;

说简单点就是:一级缓存只共享同一个sqlseeion的数据,二级缓存共享sqlsessionFactory下所有的sqlseeion的数据;

数据提取流程:

步骤一:先去缓冲区找是否存在statement

步骤二:返回结果

步骤三:如果没有缓存statement对象就到数据库获取数据

步骤四:数据库返回结果数据

步骤五:把数据库返回结果放到缓冲区中

 

补充标签常用属性:

<cache 
eviction="FIFO"  <!--回收策略为先进先出-->
flushInterval="60000" <!--自动刷新时间60s-->
size="512" <!--最多缓存512个引用对象-->
readOnly="true"/> <!--只读-->

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值