Mybatis框架|二级缓存


一、Mybatis的二级缓存

二级缓存是SqlSessionFactory级别的缓存,同一个SqlSessionFactory产生的SqlSession都共享一个二级缓存,二级缓存中存储的是数据,当命中二级缓存时,通过存储的数据构造对象返回。查询数据的时候,查询的流程是二级缓存>一级缓存>数据库

二、二级缓存的使用原则

(1)只能在一个命名空间下使用二级缓存

由于二级缓存中的数据是基于namespace的,即不同namespace中的数据互不干扰。在多个namespace中若均存在对同一个表的操作,那么这多个namespace中的数据可能就会出现不一致现象。

(2)在单表上使用二级缓存

如果一个表与其它表有关联关系,那么就有可能存在多个namespace对同一数据的操作。而不同namespace中的数据互不干扰,所以就有可能出现多个namespace中的数据不一致现象。

(3)查询多于修改时使用二级缓存

在查询操作远远多于增删改操作的情况下可以使用二级缓存。因为任何增删改操作都将刷新二级缓存,对二级缓存的频繁刷新将降低系统性能。

三、二级缓存的使用步骤

1.配置Mybatis框架支持二级缓存

Mybatis3以后已经不需要下面的语句,自身已经支持了二级缓存。

	<settings>
		<!-- 设置Mybatis支持二级缓存 -->
		<setting name="cacheEnabled" value="true"/>
	</settings>

全局配置文件如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<properties resource="db.properties"></properties>

	<settings>
		<!-- 设置延迟加载 -->
		<setting name="lazyLoadingEnabled" value="true"/>
 		<setting name="aggressiveLazyLoading" value="false"/>
 		<!-- 设置支持二级缓存 -->
 		<setting name="cacheEnabled" value="true"/>
	</settings>
	
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<!-- 使用接口的全限定名,接口名必须和sql配置文件同名且同级目录 -->
		
		<package name="com.gql.mapper"/>
	</mappers>
</configuration>

2. 配置dao层xml支持二级缓存

在dao层的xml配置中加入下面的标签,就代表dao层也支持二级缓存了。

<cache/>

dao层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">
<mapper namespace="com.gql.mapper.UserMapper">
	<!-- dao层配置开启二级缓存 -->
	<cache/>
	<select id="getUserById" parameterType="java.lang.Integer" resultType="com.gql.pojo.User">
		SELECT id,username,sex,address,birthday FROM user WHERE id = #{id};
	</select>
	<update id="updateUser" parameterType="com.gql.pojo.User">
		UPDATE user SET 
		username=#{username},
		sex=#{sex},
		address=#{address},
		birthday=#{birthday}
		WHERE id =#{id};
	</update>
</mapper>

三、测试二级缓存

全局配合和dao层配置在上面已经给出。

扫描二维码关注公众号,回复: 9171540 查看本文章

1.User对象的pojo

package com.gql.pojo;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
 * 类说明:
 *		User_JavaBean
 * @guoqianliang1998.
 */
public class User implements Serializable{

	private static final long serialVersionUID = 1L;
	private int id;
	private String username;
	private String sex;
	private String address;
	private Date birthday;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
}

2.dao层接口

package com.gql.mapper;
import java.util.List;
import com.gql.pojo.User;

/**
 * 类说明: 
 * 		接口 
 * @guoqianliang1998.
 */
public interface UserMapper {
	User getUserById(int id);

}

3.测试二级缓存

package com.gql.mapper;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
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.Before;
import org.junit.Test;

import com.gql.pojo.User;


public class UserMapperTest {
	private SqlSessionFactory sqlSessionFactory;
	@Before
	public void init() throws IOException{
		String resource = "mybatis-config.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);		
	}

	@Test
	public void testCache2(){
		//1.使用session1进行查询
		SqlSession session1 = sqlSessionFactory.openSession();
		UserMapper userMapper1 = session1.getMapper(UserMapper.class);
		User user1 = userMapper1.getUserById(1);
		System.out.println(user1.getUsername());
		//2.关闭sessin1
		session1.close();
		//3.使用session2进行查询
		SqlSession session2 = sqlSessionFactory.openSession();
		UserMapper userMapper2 = session2.getMapper(UserMapper.class);
		User user2 = userMapper2.getUserById(1);
		System.out.println(user1.getUsername());
	}
}

在debug模式下单步调试上述代码:

①session1的代理对象调用查询方法时,向数据库发送了sql命令。

在这里插入图片描述

②关闭session1,使用session2的代理对仍进行查询时,并没有执行ssql命令。在这里插入图片描述

这说明,同一个SqlSessionFactory产生的SqlSession共享同一个二级缓存,二级缓存测试成功。

发布了413 篇原创文章 · 获赞 1081 · 访问量 23万+

猜你喜欢

转载自blog.csdn.net/weixin_43691058/article/details/104312418