1. 一级缓存
一级缓存:同一个SqlSession对象
MyBatis默认开启一级缓存,如果用同样的SqlSession对象查询相同的数据,
则只会在第一次查询时向数据库发送SQL语句,并将查询的结果放入到sqlSession中(作为缓存),在后续再次查询该同样的对象时,则直接从缓存中查询该对象即可(省略了数据库的访问)
来看实例:我查了两次,到sql语句只调用了1次,说明第一次查的实际,被放入了sqlSession中
2. 执行commit()后会清理缓存,(commit通常在执行增删改后才用,这里只是举例)
如图sql语句调用了2次,如果不写commit()方法,这只会调用一次sql查询
2. 二级缓存
Mybatis默认情况没有开启二级缓存,需要手工打开。
1. 配置mybatis-config.xml文件
2. 在具体的mapper.xml文件中声明开启,例如在StudentMapper.xml中
3. 我们来尝试运行
第一次调用sqlSession.getMapper(StudentDao.class); mapper.queryStudentById(1);方法正确执行了,第二次到sqlSession2.getMapper(StudentDao.class); mapper2.queryStudentById(1);调用同一个方法,查询同一行数据,由于2个sqlSession是来自同一个namespace, 所以可以从二级缓存中拿到数据
触发将对象写入二级缓存的时机:SqlSession对象调用close()方法。
4. 运行结果
根据异常提示:NoSerializableException可知,
是没有序列化,
序列化:内存->硬盘
反序列化:硬盘->内存
5. 序列化Student类
MyBatis的二级缓存,是将对象放入硬盘中,所以,准备缓存的对象,也就是当前这个Student类,必须实现序列化接口(如果开启的缓存namespace="com.lyx.mybatis.dao.StudentDao"值相同,则通过这些xxxMapper.xml产生的xxMapper对象,任然共享二级缓存),因此需要将Student类序列化(同时序列化Student类,以及Student的级联属性、和父类)
6. 再次运行,注意调用方法后要close(),否则Mybatis不会提交缓存