一级缓存
大约 3 分钟数据库技术Mybatis
一级缓存也叫本地缓存:
- 与数据库同一次会话期间查询到的数据会放在本地缓存中。
- 以后如果需要获取相同的数据,直接从缓存中拿,没必须在去查询数据库。
一级缓存测试
相同的查询
@Test
public void test01(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user1 = userMapper.getUserById8(1);
System.out.println(user1);
User user2 = userMapper.getUserById8(1);
System.out.println(user2);
System.out.println(user1 == user2);
sqlSession.close();
}
结果
Opening JDBC Connection
Created connection 1233705144.
==> Preparing: select * from user where id = ?
==> Parameters: 1(Integer)
<== Columns: id, name, pwd
<== Row: 1, 狂神, 123456
<== Total: 1
User(id=1, name=狂神, pwd=123456)
User(id=1, name=狂神, pwd=123456)
true
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4988d8b8]
Returned connection 1233705144 to pool.
Process finished with exit code 0
可以发现,在一个sqlSession中,两次相同的查询只会查一次数据库,第二次会查一级缓存。
不同的查询
@Test
public void test01(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user1 = userMapper.getUserById8(1);
System.out.println(user1);
User user2 = userMapper.getUserById8(2);
System.out.println(user2);
System.out.println(user1 == user2);
sqlSession.close();
}
结果
Opening JDBC Connection
Created connection 1233705144.
==> Preparing: select * from user where id = ?
==> Parameters: 1(Integer)
<== Columns: id, name, pwd
<== Row: 1, 狂神, 123456
<== Total: 1
User(id=1, name=狂神, pwd=123456)
==> Preparing: select * from user where id = ?
==> Parameters: 2(Integer)
<== Columns: id, name, pwd
<== Row: 2, 法外狂徒张三, 333333
<== Total: 1
User(id=2, name=法外狂徒张三, pwd=333333)
false
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4988d8b8]
Returned connection 1233705144 to pool.
Process finished with exit code 0
可以发现,由于是两次不同的查询。查了两次数据库,没有走缓存。
相同的查询中间有update
@Test
public void test02(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user1 = userMapper.getUserById8(1);
System.out.println(user1);
/**
* update信息
*/
userMapper.updateUser8(new User(5,"小吴","555"));
User user2 = userMapper.getUserById8(1);
System.out.println(user2);
System.out.println(user1 == user2);
sqlSession.close();
}
结果
Opening JDBC Connection
Created connection 1233705144.
==> Preparing: select * from user where id = ?
==> Parameters: 1(Integer)
<== Columns: id, name, pwd
<== Row: 1, 狂神, 123456
<== Total: 1
User(id=1, name=狂神, pwd=123456)
==> Preparing: update user set name=?,pwd=? where id = ?
==> Parameters: 小吴(String), 555(String), 5(Integer)
<== Updates: 1
==> Preparing: select * from user where id = ?
==> Parameters: 1(Integer)
<== Columns: id, name, pwd
<== Row: 1, 狂神, 123456
<== Total: 1
User(id=1, name=狂神, pwd=123456)
false
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4988d8b8]
Returned connection 1233705144 to pool.
Process finished with exit code 0
可以发现,虽然两次查的都是1号用户。但是因为中间有更新2号用户的数据,缓存失效了。查了两次数据库。
手动清除缓存
@Test
public void test02(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user1 = userMapper.getUserById8(1);
System.out.println(user1);
/**
* 清理缓存
*/
sqlSession.clearCache();
User user2 = userMapper.getUserById8(1);
System.out.println(user2);
System.out.println(user1 == user2);
sqlSession.close();
}
结果
Opening JDBC Connection
Created connection 1233705144.
==> Preparing: select * from user where id = ?
==> Parameters: 1(Integer)
<== Columns: id, name, pwd
<== Row: 1, 狂神, 123456
<== Total: 1
User(id=1, name=狂神, pwd=123456)
==> Preparing: select * from user where id = ?
==> Parameters: 1(Integer)
<== Columns: id, name, pwd
<== Row: 1, 狂神, 123456
<== Total: 1
User(id=1, name=狂神, pwd=123456)
false
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4988d8b8]
Returned connection 1233705144 to pool.
Process finished with exit code 0
可以发现,手动清除缓存之后。相同的查询查了两次数据库。
缓存失效
- 不同的查询SQL。
- 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。增删改可能会改变原来的数据,所以需要刷新缓存。
- 查询不同的mapper.xml
- 手动清除缓存
理解
默认开启。只在一次SqlSession中有效,也就是在拿到连接和关闭连接这个区间有效。一级缓存就是一个map。
