Mybatis框架|一级缓存


一、程序中的缓存

所谓的缓存,就是将程序或系统经常要调用的对象(临时数据)存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少和数据库的交互次数,提高效率。

什么样的数据能使用缓存,什么样的数据不能使用?

  • 适用于缓存的数据:经常查询并且不经常改变的,并且数据的正确与否对最终结果影响不大。
  • 不适用于缓存的数据:经常改变的数据,数据的正确与否对最终结果影响很大的。
  • MyBatis目前的缓存方式在多表操作时是无解的,使用Mybatis进行多表操作不要进行缓存。

二、Mybatis的一级缓存

Mybatis的一级缓存指的是Mybatis中sqlSession对象的缓存,当我们执行查询以后,查询的结果会同时存入到SqlSession为我们提供的一块区域中,该区域的底层结构是一个Map,当我们再次查询同样的数据,mybatis会先去sqlsession中查询是否有,有的话直接拿出来用。一级缓存是SqlSession范围的缓存,当SqlSession对象消失时,mybatis的一级缓存也就消失了。如果调用SqlSession的修改、添加、删除、commit(),close等方法时,就会清空一级缓存。

  • Mybatis默认支持一级缓存,当Mybatis与Spring整合后,一级缓存就失效了。

总结:mybatis的一级缓存是SqlSession级别的缓存,一级缓存缓存的是对象,当SqlSession提交、关闭以及其他的更新数据库的操作发生后,一级缓存就会清空。

三、测试Mybatis的一级缓存

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);

	void updateUser(User user);

}

3.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">

	<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>

4.测试一级缓存

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 testCache1(){
		SqlSession session = sqlSessionFactory.openSession();
		UserMapper userMapper = session.getMapper(UserMapper.class);
		//第一次查询数据库
		User user1 = userMapper.getUserById(1);
		System.out.println(user1.getUsername());
		//更新一级缓存
		user1.setUsername("周冬雨");
		userMapper.updateUser(user1);
		session.commit();
		//第二次查询数据库
		User user2 = userMapper.getUserById(1);
		System.out.println(user2.getUsername());
	}
}

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

①第一次查询数据库时,执行了sql语句,并向SqlSession添加了缓存。
在这里插入图片描述
②当执行了更新啊哦做commit后,SqlSession缓存被清空了。
在这里插入图片描述
③当再次执行查询数据库时,由于SqlSession已经被清空,仍然需要进行数据库的查询。
在这里插入图片描述

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

猜你喜欢

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