• MyBatis的缓存分析


    一:MyBatis缓存简介

    MyBatis支持声明式数据缓存(declarative data caching)。当一条SQL语句被标记为“可缓存”后,首次执行它时从数据库获取的所有数据会被存储在一段高速缓存中,今后执行这条语句时就会从高速缓存中读取结果,而不是再次命中数据库。MyBatis提供了默认下基于Java HashMap的缓存实现,以及用于与OSCache、Ehcache、Hazelcast和Memcached连接的默认连接器。MyBatis还提供API供其他缓存实现使用。

      MyBatis执行SQL语句之后,这条语句就是被缓存,以后再执行这条语句的时候,会直接从缓存中拿结果,而不是再次执行SQL,这就是所说的一级缓存。一级缓存的作用域scope是SqlSession。

    一级缓存

     测试

    同个session进行两次相同查询:

     1 @Test
     2 public void test() {
     3     SqlSession sqlSession = sqlSessionFactory.openSession();
     4     try {
     5         User user = (User)sqlSession.selectOne("org.format.mybatis.cache.UserMapper.getById", 1);
     6         log.debug(user);
     7         User user2 = (User)sqlSession.selectOne("org.format.mybatis.cache.UserMapper.getById", 1);
     8         log.debug(user2);
     9     } finally {
    10         sqlSession.close();
    11     }
    12 }
    test

    MyBatis只进行1次数据库查询:

    1 ==>  Preparing: select * from USERS WHERE ID = ? 
    2 ==> Parameters: 1(Integer)
    3 <==      Total: 1
    4 User{id=1, name='format', age=23, birthday=Sun Oct 12 23:20:13 CST 2017}
    5 User{id=1, name='format', age=23, birthday=Sun Oct 12 23:20:13 CST 2017}
    结果

    同个session进行两次不同的查询:

     1 @Test
     2 public void test() {
     3     SqlSession sqlSession = sqlSessionFactory.openSession();
     4     try {
     5         User user = (User)sqlSession.selectOne("org.format.mybatis.cache.UserMapper.getById", 1);
     6         log.debug(user);
     7         User user2 = (User)sqlSession.selectOne("org.format.mybatis.cache.UserMapper.getById", 2);
     8         log.debug(user2);
     9     } finally {
    10         sqlSession.close();
    11     }
    12 }
    test

    MyBatis进行两次数据库查询:

    1 ==>  Preparing: select * from USERS WHERE ID = ? 
    2 ==> Parameters: 1(Integer)
    3 <==      Total: 1
    4 User{id=1, name='format', age=23, birthday=Sun Oct 12 23:20:13 CST 2017}
    5 ==>  Preparing: select * from USERS WHERE ID = ? 
    6 ==> Parameters: 2(Integer)
    7 <==      Total: 1
    8 User{id=2, name='FFF', age=50, birthday=Sat Dec 06 17:12:01 CST 2017}
    结果

    不同session,进行相同查询:

     1 @Test
     2 public void test() {
     3     SqlSession sqlSession = sqlSessionFactory.openSession();
     4     SqlSession sqlSession2 = sqlSessionFactory.openSession();
     5     try {
     6         User user = (User)sqlSession.selectOne("org.format.mybatis.cache.UserMapper.getById", 1);
     7         log.debug(user);
     8         User user2 = (User)sqlSession2.selectOne("org.format.mybatis.cache.UserMapper.getById", 1);
     9         log.debug(user2);
    10     } finally {
    11         sqlSession.close();
    12         sqlSession2.close();
    13     }
    14 }
    test

    MyBatis进行了两次数据库查询:

    1 ==>  Preparing: select * from USERS WHERE ID = ? 
    2 ==> Parameters: 1(Integer)
    3 <==      Total: 1
    4 User{id=1, name='format', age=23, birthday=Sun Oct 12 23:20:13 CST 2017}
    5 ==>  Preparing: select * from USERS WHERE ID = ? 
    6 ==> Parameters: 1(Integer)
    7 <==      Total: 1
    8 User{id=1, name='format', age=23, birthday=Sun Oct 12 23:20:13 CST 2017}
    结果

    同个session,查询之后更新数据,再次查询相同的语句:

     1 @Test
     2 public void test() {
     3     SqlSession sqlSession = sqlSessionFactory.openSession();
     4     try {
     5         User user = (User)sqlSession.selectOne("org.format.mybatis.cache.UserMapper.getById", 1);
     6         log.debug(user);
     7         user.setAge(100);
     8         sqlSession.update("org.format.mybatis.cache.UserMapper.update", user);
     9         User user2 = (User)sqlSession.selectOne("org.format.mybatis.cache.UserMapper.getById", 1);
    10         log.debug(user2);
    11         sqlSession.commit();
    12     } finally {
    13         sqlSession.close();
    14     }
    15 }
    test

    更新操作之后缓存会被清除:

     1 ==>  Preparing: select * from USERS WHERE ID = ? 
     2 ==> Parameters: 1(Integer)
     3 <==      Total: 1
     4 User{id=1, name='format', age=23, birthday=Sun Oct 12 23:20:13 CST 2017}
     5 ==>  Preparing: update USERS SET NAME = ? , AGE = ? , BIRTHDAY = ? where ID = ? 
     6 ==> Parameters: format(String), 23(Integer), 2017-10-12 23:20:13.0(Timestamp), 1(Integer)
     7 <==    Updates: 1
     8 ==>  Preparing: select * from USERS WHERE ID = ? 
     9 ==> Parameters: 1(Integer)
    10 <==      Total: 1
    11 User{id=1, name='format', age=23, birthday=Sun Oct 12 23:20:13 CST 2017}
    结果

    很明显,结果验证了一级缓存的概念,在同个SqlSession中,查询语句相同的sql会被缓存,但是一旦执行新增或更新或删除操作,缓存就会被清除

  • 相关阅读:
    day11课堂小结 函数作用域
    猜年龄函数版day10作业
    函数day10课堂小结
    day07作业
    文件处理day09
    编码day08
    默写
    day07课堂小结
    day06作业
    const与define应用上该怎么取舍
  • 原文地址:https://www.cnblogs.com/nullering/p/9310036.html
Copyright © 2020-2023  润新知