首页 > 其他 > 详细

Mybatis缓存

时间:2019-08-12 20:16:45      阅读:101      评论:0      收藏:0      [点我收藏+]
像大多数的持久化框架一样,Mybatis 也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提
高性能。
Mybatis 中缓存分为一级缓存,二级缓存。

技术分享图片

 

1. Mybatis一级缓存

   1.1 证明一级缓存的存在

    一级缓存是session级别的缓存,只要sqlSession没有flush或者close,它就存在。无需配置

    1.1.1 编写用户持久层接口

/**
 * 用户的持久层接口
 * Ceate By llb on 2019/8/5
 */
public interface UserMapper {
    /**
     * 根据id查询用户
     * @return
     */
    User findUserById(int id);

}

    1.1.2 编写用户持久层映射文件

    

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.llb.dao.UserMapper">
    <!--useCache-->
    <select id="findUserById" resultType="user" parameterType="int" useCache="true">
        select * from user where id = #{id}
    </select>
</mapper>

    1.1.3 编写测试方法

package com.llb.test;

/**
 * Ceate By llb on 2019/8/5
 */
public class UserTest {

    InputStream in = null;
    UserMapper mapper = null;
    SqlSession sqlSession = null;
    SqlSessionFactory factory = null;
    /**
     * 在测试方法执行前执行
     * @throws IOException
     */
    @Before
    public void init() throws IOException {
        //1.读取配置文件,生成字节流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.获取sqlSessionFactory对象
        factory = new SqlSessionFactoryBuilder().build(in);
        //3.获取sqlSession对象
        sqlSession = factory.openSession();
        //4.获取dao的代理对象
        mapper = sqlSession.getMapper(UserMapper.class);
    }

    /**
     * 测试方法执行后执行
     * @throws IOException
     */
    @After
    public void destory() throws IOException {
        sqlSession.commit();
        //6.释放资源
        sqlSession.close();
        in.close();
    }
    /**
     * 根据id查询用户,sqlSession一级缓存:
     *  当调用sqlSession的修改、添加、删除,commit() ,close(),clear()等方法时,会清空缓存
     */
    @Test
    public void findUserById(){
        User user = mapper.findUserById(41);

        User user2 = mapper.findUserById(41);

        System.out.println(user == user2);
    }

}

    测试结果:

      技术分享图片

    

我们虽然查询了两次,但最后只查询了一次数据库,这就是Mybatis提供给我们得一级缓存起作用。因为一级缓存的存在,导致第二次查询id为41的记录时,并没有发出sql语句从数据库中查询数据,而是从一级缓存中查询。

    1.1.2 一级缓存的分析

      一级缓存是SqlSession范围的缓存,当调用SqlSession的修改、添加、删除时、commit、close等方法就会清空缓存。

技术分享图片

 

第一次发起查询用户 id 为 1 的用户信息,先去找缓存中是否有 id 为 1 的用户信息,如果没有,从数据库查询用户信息。
  得到用户信息,将用户信息存储到一级缓存中。
  如果 sqlSession 去执行 commit 操作(执行插入、更新、删除),清空 SqlSession 中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。
  第二次发起查询用户 id 为 1 的用户信息,先去找缓存中是否有 id 为 1 的用户信息,缓存中有,直接从缓存中获取用户信息。

    2.1.3 测试一级缓存的清空

      

    /**
     * 根据id查询用户,sqlSession一级缓存:
     *  当调用sqlSession的修改、添加、删除,commit() ,close(),clear()等方法时,会清空缓存
     */
    @Test
    public void findUserById(){
        User user = mapper.findUserById(41);

        //关闭sqlSession会清空缓存
        sqlSession.close();
        sqlSession = factory.openSession();
        mapper = sqlSession.getMapper(UserMapper.class);

        //直接对sqlSession进行清空
//        sqlSession.clearCache();

        User user2 = mapper.findUserById(41);

        System.out.println(user == user2);
    }
技术分享图片

当执行sqlSession.close()后,再次获取sqlSession并查询id=41的User对象时,又重新执行了sql 语句,从数据库进行了查询操作。导致两个用户的地址不一致。

 

  

    

 

Mybatis缓存

原文:https://www.cnblogs.com/liulebin/p/11342087.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!