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
    }
}

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

运行时参数相关

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

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

操作与配置相关

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值