Mybatis一级缓存与二级缓存

本文介绍了Mybatis的一级缓存和二级缓存。一级缓存默认开启,存在于SqlSession内部,增删改操作后会自动清空。二级缓存需要手动开启,跨SqlSession共享,增删改后同样清空。flushCache='true'表示查询结果不缓存。
摘要由CSDN通过智能技术生成

mybatis的有两种缓存,一级缓存和二级缓存。两个缓存的不同点和相同点总结如下

不同点:

  • 一级缓存存在于一个SqlSession之内,二级缓存存在于不同的SqlSession之间
  • 一级缓存不需要手动开启,属于默认开启状态;二级缓存需要手动开启

相同点:

  • 在增删改SQL之后,缓存会自动清空
  • flushCache="true"的查询语句查询内容不存放进缓存

 

一级缓存

一级缓存是mybatis自带的缓存,mybatis每次在查询后,会将语句和参数相同的查询SQL的结果集存放进缓存,待下一次有相同的语句和参数时,mybatis直接将缓存内的结果集返回,而不再查询数据库。如果对于缓存的数据对应的表有增删改操作的话,缓存自动清空。

通过实际的代码测试来看,在上一次一个简单的mybatis入门demo的基础上改造工程

增加BaseMaperTest.java类,用以进行SqlSession的获取

package cn.mybatis.xml;

import java.io.IOException;
import java.io.Reader;

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.BeforeClass;

/**
 * 设置mapper测试父类
 * 用以进行数据库连接,获取SqlSession
 * @author PC
 */
public class BaseMapperTest {

	private static SqlSessionFactory sqlSessionFactory;
	
	/**
	 * 进行数据库连接
	 */
	@BeforeClass
	public static void init() {
		try {
			Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取SqlSession
	 * @return
	 */
	public SqlSession getSqlSession() {
		return sqlSessionFactory.openSession();
	}
}

在CountryMapper.java中增加根据id查询方法,增加一个addCountry方法

	/**
	 * 查询国家/地区
	 * @param id 查询id
	 * @return 查询到的国家/地区
	 */
	Country selectCountryById(Long id);
	
	/**
	 * 添加国家/地区
	 * @param country
	 * @return 影响的数据条数
	 */
	int addCountry(Country country);

对应CountryMapper.xml配置文件

	<select id="selectCountryById" resultType="cn.mybatis.xml.model.Country">
		select id, countryname, countrycode 
		from country
		where id = #{id}
	</select>
	
	<insert id="addCountry">
		insert into country(id, countryname, countrycode)
		values(#{id}, #{countryname}, #{countrycode})
	</insert>

通过Junit来测试,三种场景,分别来测试

  • 缓存后,直接查询
	/**
	 * 一级缓存测试
	 * 测试缓存后,再查询
	 */
	@Test
	public void testCache1() {
		SqlSession sqlSession = getSqlSession();
		try {
			// 第一次查询
			Country country = sqlSession.selectOne("selectCountryById", 2l);
			System.out.println(country.getCountryname() + ":" + country.getCountrycode());
			
			// 通过日志可以发现,第二次查询并未到数据库查数据,说明第二次走的是缓存
			Country country2 = sqlSession.selectOne("selectCountryById", 2l);
			System.out.println(country2.getCountryname() + ":" + country2.getCountrycode());
		} finally {
			sqlSession.close();
		}
	}

执行后,可以看到日志

Opening JDBC Connection
Created connection 1291113768.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4cf4d528]
==>  Preparing: select id, countryname, countrycode from country where id = ? 
==> Parameters: 2(Long)
<==    Columns: id, countryname, countrycode
<==        Row: 2, 美国, US
<==      Total: 1
美国:US
美国:US
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4cf4d528]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4cf4d528]
Returned connection 1291113768 to pool.

反馈了两次查询结果,但是只查询了一次数据库,说明第二次的查询是取得缓存结

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值