mybatis中的缓存问题解析

  

关于mybatis基础我们前面几篇博客已经介绍了很多了,今天我们来说一个简单的问题,那就是mybatis中的缓存问题.mybatis本身对缓存提供了支持,但是如果我们没有进行任何配置,那么默认情况下系统只开启了一级缓存,一级缓存就是同一个SqlSession执行的相同查询是会进行缓存的,好的,那么今天我们就来看看这些缓存,并简单验证下。

  

<强>系统默认开启了一级缓存

  

这个缓存系统默认情况下是开启的,当我们获取到一个SqlSession对象之后,如果调用SqlSession中的同一个方法查询同一条数据,那么第二次查询将不会去数据库中查询,因为第一次查询有缓存,直接调用缓存数据即可,除非缓存超时或者我们明确声明数据要刷新,否则都是直接调用缓存数据对吧,我们来看一个简单的案例。
  查询代码如下:

        SqlSession SqlSession=零;   尝试{   sqlSession=DBUtils.openSqlSession ();   usermap mapper=sqlSession.getMapper (UserMapper.class);//查询同一条数据时会缓存   用户用户=mapper.getUser(1升);   用户user2=mapper.getUser(1升);   System.out.println (user.toString ());   System.out.println (user2.toString ());   sqlSession.commit ();   }捕捉(异常e) {   System.err.println (e.getMessage ());   sqlSession.rollback ();   最后}{   如果(sqlSession !=null) {   sqlSession.close ();   }   }      

我们来看看日志:
  

  

 mybatis中的缓存问题解析”>,<br/>
  </p>
  <p>小伙伴们看的到,我这里执行了两次查询,但实际上只执行了一次SQL语句。</p>
  <p> <>强自己配置二级缓存</强> </p>
  <p>上面的缓存是由系统默认配置的,这个有一定的局限性,就是只能在同一个SqlSession中有效,脱离了同一个SqlSession就没法使用这个缓存了,有的时候我们可能希望能够跨SqlSession进行数据缓存。那么这个时候需要我们进行手动开启二级缓存。<br/>
  </p>
  <p>二级缓存的开启方式其实很简单,只需要我们在userMapper.xml中配置& lt;缓存/祝辞节点即可。如下:</p>
  
  <pre类=   & lt; & # 63; xml version=" 1.0 " encoding=" utf - 8 " & # 63;比;   & lt; !文档类型映射器   公众”——//mybatis.org//DTD Mapper 3.0//EN”   “http://mybatis.org/dtd/mybatis-3-mapper.dtd”在   & lt;映射器命名空间=皁rg.sang.db.UserMapper”比;   & lt;缓存/比;   & lt;选择id=" getUser " resultType=" org.sang.bean。用户“parameterType=俺ぁ痹?   select *从用户id=# {id}   & lt;/select>   & lt;插入id=" insertUser " parameterType=皁rg.sang.bean.User”比;   插入用户(用户名、密码、地址)值(# {username},{密码}#,#{地址})   & lt;/insert>   & lt;删除id=" deleteUser " parameterType=俺ぁ北?   删除从用户id=# {id}   & lt;/delete>   & lt;选择id=" getAll " resultType=皍”比;   从用户选择*   & lt;/select>   & lt;/mapper>      之前      

这样简单配置之后,二级缓存就算开启了,这样的配置中,许多东西都是默认的,比如所有的选择语句都会被缓存,所有的删除、插入和更新则都会将缓存刷新,还比如缓存将使用LRU算法进行内存回收等。那么这些东西如果需要配置的话,我们可以按如下方式进行配置:
  

  

& lt;缓存回收=癓RU flushInterval=" 20000 "大?" 1024 "只读的=" true "/祝辞,这里的驱逐表示缓存策略,除了LRU之外还有先进先出(FIFO),软引用(软)、弱引用(弱)等,flushInterval则表示刷新时间,表示缓存的对象个数,只读的为真则表示缓存只可以读取不可以修改。
  

  

好的,做了如上配置之后还不够,开启二级缓存还要求我们的实体类可以序列化,实现可序列化的接口即可,如下:

        公开课用户实现了Serializable {   私人长id;   私人字符串的用户名;   私人密码字符串;   私人字符串地址;      …      }      之前      

如此之后,我们的二级缓存就算成功开启了,好吧,我么来测试下:

        SqlSession SqlSession=零;   SqlSession sqlSession2=零;   尝试{   sqlSession=DBUtils.openSqlSession ();   usermap mapper=sqlSession.getMapper (UserMapper.class);   用户用户=mapper.getUser(1升);   System.out.println (user.toString ());   sqlSession.commit ();   sqlSession2=DBUtils.openSqlSession ();   usermap mapper2=sqlSession2.getMapper (UserMapper.class);   用户user2=mapper2.getUser(1升);   System.out.println (user2.toString ());   sqlSession2.commit ();   }捕捉(异常e) {   System.err.println (e.getMessage ());   sqlSession.rollback ();   sqlSession2.rollback ();   最后}{   如果(sqlSession !=null) {   sqlSession.close ();   }   如果(sqlSession2 !=null) {   sqlSession2.close ();   }   }      

mybatis中的缓存问题解析