介绍
MyBatis连接数据库时,会创建 SqlSession对象,在 SqlSession 对象中有一个简单的缓存(由Map实现),将每次查询到的结果缓存起来
再次查询时,如果是同一个 sql,就从缓存中直接将结果取出
特点
默认开启一级缓存
必须是同一个SqlSession
调用了
sqlSession.close()方法,关闭数据库连接,同时释放一级缓存再次执行同一个sql,不想从缓存中提取,需要在查询前执行
sqlSession.clearCache();,清空缓存当
sqlSession执行insertsql语句、deletesql语句、updatesql语句、或者执行commit()方法时,会清空一级缓存
测试一级缓存
@Test
public void testSelect() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
IPostMapper mapper = sqlSession.getMapper(IPostMapper.class);
//执行第一次查询
List<PostUser> list=mapper.query();
//执行第二次查询
list=mapper.query();
for(PostUser p:list) {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm");
String createTime=sdf.format(p.getCreateTime());
String info = String.format("id:%s,标题:%s,用户名:%s,创建时间:%s", p.getId(), p.getTitle(), p.getUsername(),createTime);
System.out.println(info);
}
sqlSession.close();
inputStream.close();
}
在控制台中只显示一条sql语句,说明第二次查询,没有执行sql,而是从缓存中提取的
DEBUG [main] - ==> Preparing: select p.id,p.title,p.create_time,p.user_id,u.username from user u,post p where u.id=p.user_id
DEBUG [main] - ==> Parameters:
DEBUG [main] - <== Total: 3
测试清空缓存
@Test
public void testSelect() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
IPostMapper mapper = sqlSession.getMapper(IPostMapper.class);
//执行第一次查询
List<PostUser> list=mapper.query();
//清空缓存
sqlSession.clearCache();
//执行第二次查询
list=mapper.query();
for(PostUser p:list) {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm");
String createTime=sdf.format(p.getCreateTime());
String info = String.format("id:%s,标题:%s,用户名:%s,创建时间:%s", p.getId(), p.getTitle(), p.getUsername(),createTime);
System.out.println(info);
}
sqlSession.close();
inputStream.close();
}
清空缓存后,再次执行相同的sql,会再次查询数据库,在控制台中也能看到,打印2条sql
DEBUG [main] - ==> Preparing: select p.id,p.title,p.create_time,p.user_id,u.username from user u,post p where u.id=p.user_id
DEBUG [main] - ==> Parameters:
DEBUG [main] - <== Total: 3
DEBUG [main] - ==> Preparing: select p.id,p.title,p.create_time,p.user_id,u.username from user u,post p where u.id=p.user_id
DEBUG [main] - ==> Parameters:
DEBUG [main] - <== Total: 3
增删改 会清空缓存
@Test
public void testSelectById() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
IUserMapper mapper = sqlSession.getMapper(IUserMapper.class);
User u=mapper.selectById("10001");
String info = String.format("id:%s,用户名:%s,密码:%s", u.getId(), u.getUsername(), u.getPassword());
System.out.println(info);
User user=new User();
user.setId("1000");
user.setUsername("admin2");
user.setPassword("12345678");
int num=mapper.updateById(user);
System.out.println("更新 "+num+" 条记录");
u=mapper.selectById("10001");
info = String.format("id:%s,用户名:%s,密码:%s", u.getId(), u.getUsername(), u.getPassword());
System.out.println(info);
sqlSession.close();
inputStream.close();
}
控制台打印如下:
在控制台中打印2条相同的查询语句,说明执行 update 语句后,再次执行相同的查询sql时,会再次查询数据库

