一级缓存和二级缓存

版权声明:@渔闻520 https://blog.csdn.net/weixin_41060905/article/details/86673114

一级缓存是在SQLSession上的缓存,二级缓存是在SQLSessionFactory上的缓存,默认情况下,也就是没有任何配置的情况下,MyBatis系统会开启一级缓存,也就是SQLSession层面上的缓存,这个缓存不需要POJO对象的可序列化。即:

当一个SQLSession第一次通过SQL和参数获取对象后,他就会将其缓存起来,如果下次的SQL和参数都没有发生变化,并且缓存没有超时(关于时间,在cache的配置项里有一个flushInterval属性,默认值为null,也就是没有刷新时间,只有当执行update,delete,insert时才会刷新)或者需要声明刷新,那么他就会从缓存中读取数据,而不是通过SQL获取。即通过一个SQLSession获得映射器接口A,下次再用这个接口A来获得数据,还是一样的(需要满足上述前提条件)。

 SqlSession sqlSession=null;
  try {
          sqlSession=SqlSessionFactoryUtils.openSqlSession();
          RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
          Role role = roleMapper.getRole(1);
          log.info(role.getRoleName());
          log.info("再取一次pojo");
          Role role1=roleMapper.getRole(1);

比如上面的代码就会只执行一次sql,下一个执行就调用缓存。

另外一级缓存是在SqlSession层面的,对于不同的SqlSession对象是不能共享的。例如:

 Logger log = Logger.getLogger(String.valueOf(Chapter3Main.class));
                    SqlSession sqlSession=null;
                    SqlSession sqlSession1=null;
                    try {
                        sqlSession=SqlSessionFactoryUtils.openSqlSession();
                        RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
                        Role role = roleMapper.getRole(1);
                        log.info(role.getRoleName());
                        //需要提交
                        sqlSession.commit();
                        log.info("不同SQLSession再取一次pojo");
                         sqlSession1 = SqlSessionFactoryUtils.openSqlSession();
                        RoleMapper mapper = sqlSession1.getMapper(RoleMapper.class);
                        Role role1=mapper.getRole(1);
                        //需要提交
                        sqlSession1.commit();

而有些时候需要在SqlSession之间共享相同的缓存,这个时候就要开启二级缓存,开启二级缓存需要对象的序列化。先要在映射文件中(RoleMapper.xm)加入:

<cache/>

另外由于需要对象序列化,故要让对应pojo对象实现Serializable接口。

public class Role implements Serializable {
    //这个serialVersionUID值不是必须的,但是最好写上,便于版本
    public static final long serialVersionUID= -8458445228523031014L;

那个UID可以在idea中自动生成。(alt+enter)。这个UID可以解决不兼容性的问题。当然不写也是可以的,就是没有考虑到不兼容的问题。

这个时候,不同的SqlSession在获取同一条的记录的时候,都是发送一次的SQL来获取数据。因为这个时候的数据是保存在SqlSessionFactory层面,可以提供给任何的SqlSession使用。只是他需要一个序列化和反序列化的过程而已。

在现实中,可以使用Redis,MongoDB 等其他缓存,如果有这么一个缓存实现类com.ssm.chapter3.cache.RedisCache,那么可以这样配置它:

<cache type="com.ssm.chapter3.cache.RedisCache">

<property name="host" value="localhost"/>

</cache>.

还有,如果一些语句如果想要自定义,比如一些查询并不想要它进行缓存,可以:

<select ``````flushCache="false" useCache="true"/>

<insert````flushCache="true"/>

注意:useCache属性是select特有的。

猜你喜欢

转载自blog.csdn.net/weixin_41060905/article/details/86673114