一级缓存也叫本地缓存: SqlSession
- 与数据库同一次会话期间查询到的数据会放在本地缓存中
- 以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库
1.案例:测试一级缓存
由于一级缓存默认开启(我们不能关闭,但是可以清除),所以我们只需要去获取它就行了,这里我们通过查询只当ID的用户来进行测试
创建新model:MyBatis-09
-
要查看一级缓存,我们需要去开启日志
方式:直接去mybatis核心配置文件中使用setting节点,并且设置它的logImpl属性,这里我们就使用标准日志输出即可,没有按照查看日志的插件,所以log4j的日志读起来比较麻烦<setting name="logImpl" value="STDOUT_LOGGING"/>
-
这个例子就使用比较简单的用户表,所以直接去创建pojo
package com.thhh.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @NoArgsConstructor @AllArgsConstructor @Data public class User { private int id; private String name; private String pwd; }
-
创建接口
package com.thhh.dao; import com.thhh.pojo.User; import org.apache.ibatis.annotations.Param; public interface UserMapper { //1、根据用户ID查询用户信息 User queryUserById(@Param("uid") int id); }
-
编写mapper.xml
<?xml version="1.0" encoding="UTF8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.thhh.dao.UserMapper"> <select id="queryUserById" resultType="user" parameterType="_int"> select * from user where id = #{uid} </select> </mapper>
-
测试
package com.thhh.dao; import com.thhh.pojo.User; import com.thhh.utils.MyBatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test; public class TestUserMapper { @Test public void testQueryUserById(){ SqlSession sqlSession = MyBatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user1 = mapper.queryUserById(3); System.out.println(user1); System.out.println("==============="); User user2 = mapper.queryUserById(3); System.out.println(user2); System.out.println("==============="); System.out.println("两个对象是否相等 = "+(user1==user2)); sqlSession.close(); } }
原因
第二次没有再去数据库中进行查找是因为我们需要查找的数据已经存储在缓存中了,你一进行查询,就直接从缓存中获取到了数据,所以就没有再去查询数据库,对应的也就没有SQL输出
2.缓存失效情况
缓存清除策略:就是说在什么情况下我们将对缓存进行清理,以及怎么进行清理;因为缓存是在内存中,内存的资源大小固定且宝贵,当然不会任由缓存一直增加
什么是缓存失效?
缓存失效指的是缓存中存储的数据丢失,下一次再次查询原来缓存中存储过的数据的时候,需要重新连接数据库进行查询;而不是指的缓存这个机制不能用了;所以缓存失效一般都是原来的缓存被新缓存覆盖
缓存失效的4种情况
-
查询不同的数据
-
任何对数据库的增删改操作都会使得缓存失效,原因:因为对数据库的修改操作,不管是增删改中的哪一个,缓存都是不能判断此时缓存的数据是不是已经被修改了,所以它为了数据一致性就让缓存失效了
- 接口
package com.thhh.dao; import com.thhh.pojo.User; import org.apache.ibatis.annotations.Param; public interface UserMapper { //1、根据用户ID查询用户信息 User queryUserById(@Param("uid") int id); //2、插入数据 int insertUser(User user); }
- mapper.xml
<insert id="insertUser" parameterType="User"> insert into user (id,name,pwd) values (#{id},#{name},#{pwd}) </insert>
- 测试
@Test public void testInsertUser(){ SqlSession sqlSession = MyBatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user1 = mapper.queryUserById(3); System.out.println("====================================="); int i = mapper.insertUser(new User(9, "9号", "123")); System.out.println("数据库影响行数 = "+i); System.out.println("====================================="); User user3 = mapper.queryUserById(3); sqlSession.close(); }
3. 使用不同的mapper.xml进行数据库的操作,原因:一个POJO对应一个mapper.xml文件,一个POJO也对应数据库中的一张表,使用不同的mapper.xml进行数据库操作显然已经不是原来的那张数据表的数据了,所以将缓存失效
4. 手动清理缓存,即在sqlsession的生命周期内,我们手动的调用sqlSession.clearCache()将会手动的清理一级缓存
@Test
public void testInsertUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user1 = mapper.queryUserById(3);
sqlSession.clearCache();
System.out.println("=====================================");
User user3 = mapper.queryUserById(3);
sqlSession.close();
}
3.小结
一级缓存默认开启,只在一次sqlsession中有效
一级缓冲就是一个Map