Mybatis源码学习二一级缓存

导读:本篇文章讲解 Mybatis源码学习二一级缓存,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一级缓存流程

Mybatis源码学习二一级缓存

一级缓存有效的因素

Mybatis源码学习二一级缓存

一级缓存有效测试

public class User {
    private Integer id;
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public interface UserMapper {

    @Select("select name from user where id = #{id}")
    String selectById(@Param("id") int id);

    @Update("update user set name=#{arg1} where id=#{arg0}")
    void updateById(int id,String name);

    @Select("select * from user where id = #{id}")
    User selectUserById(@Param("id") int id);

    @Select("select * from user where id = #{id}")
    User selectUserById2(@Param("id") int id);
}

public class FirstCacheTest {

    private SqlSessionFactory sqlSessionFactory;
    private SqlSession sqlSession;

    @Before
    public void init() throws IOException {
        //获取构造器
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //解析XML 并构造会话工厂
        sqlSessionFactory = builder.build(Resources.getResourceAsStream("mybatis-config.xml"));
        sqlSession = sqlSessionFactory.openSession();
    }

    /**
     * SQL和参数必须相同
     */
    @Test
    public void test1(){
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user1 = userMapper.selectUserById(1);
        User user2 = userMapper.selectUserById(1);
        System.out.println(user1==user2); //true 表示走一级缓存
    }
    /**
     * 必须是相同的statementID
     */
    @Test
    public void test2(){
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //statementID: dao.UserMapper.selectUserById
        User user1 = userMapper.selectUserById(1);
        //statementID: dao.UserMapper.selectUserById2
        User user2 = userMapper.selectUserById2(1);
        System.out.println(user1==user2); //false
    }

    /**
     * sqlSession必须一样,一级缓存也叫会话级缓存
     */
    @Test
    public void test3(){
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user1 = userMapper.selectUserById(1);
        User user2 = sqlSessionFactory.openSession().getMapper(UserMapper.class).selectUserById(1);
        System.out.println(user1==user2); //false
    }

    /**
     * RowBounds 返回行范围必须相同
     */
    @Test
    public void test4(){
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user1 = userMapper.selectUserById(1);
        //分页
        RowBounds rowBounds = new RowBounds(0, 1);
        List list = sqlSession.selectList("dao.UserMapper.selectUserById",1,rowBounds);
        System.out.println(user1==list.get(0)); //false
    }

    /**
     * 未手动清空缓存
     * 未执行update (数据一致性)
     * 未提交或回滚
     */
    @Test
    public void test5(){
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user1 = userMapper.selectUserById(1);
        //sqlSession.clearCache();
        //userMapper.updateById(2,"eee");
        sqlSession.commit();
        User user2 = userMapper.selectUserById(1);
        System.out.println(user1==user2); //false
    }
}

 源码分析一级缓存失效原因

运行时参数相关

Mybatis源码学习二一级缓存

首先从localCache 中获取数据,先判断key 的组成。

Mybatis源码学习二一级缓存

 key是在Executor里,而Executor在SqlSession里,所以必须是在同一个会话中。5:mysql是设置的环境,一般操作肯定是在同一个环境中,可以不考虑。

操作与配置相关

Mybatis源码学习二一级缓存

queryStack是用于嵌套查询的,等于0表示没有子查询。子查询依赖一级缓存,不能删除缓存。

Mybatis源码学习二一级缓存

Mybatis源码学习二一级缓存

Mybatis源码学习二一级缓存

Mybatis源码学习二一级缓存

Mybatis源码学习二一级缓存

清除缓存的操作完全符合之前的描述。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/1268.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!