zoukankan      html  css  js  c++  java
  • MyBatis常见的问题以及原理

    1 MyBatis缓存

    1.1 一级缓存

    MyBatis的一级缓存默认开启,作用范围是SqlSession级别的,也就是说某个SqlSession进行某个查询操作后会将该结果暂时缓存起来,而后在所有的SqlSession没有对该表进行插入、修改、删除操作的情况下,当这个SqlSession再次发起此查询时SqlSession不会去数据库执行查询操作,而是直接从缓存拿出上次查询的结果。不同的SqlSession之间缓存的数据互不影响。

    经过测试,发现使用同一个SqlSession执行了两次查询,代码如下:

    @GetMapping("/list")
    	public List<User> getAllUser() {
    		List<User> users = userMapper.selectAll();
    		List<User> users1 = userMapper.selectAll();
    		return users;
    	}
    

    结果:

    2019-04-22 10:58:11.974 DEBUG 9168 --- [nio-8080-exec-2] c.f.m.mapper.UserMapper.selectAll        : ==>  Preparing: SELECT * FROM user 
    2019-04-22 10:58:11.975 DEBUG 9168 --- [nio-8080-exec-2] c.f.m.mapper.UserMapper.selectAll        : ==> Parameters: 
    2019-04-22 10:58:11.976 DEBUG 9168 --- [nio-8080-exec-2] c.f.m.mapper.UserMapper.selectAll        : <==      Total: 2
    2019-04-22 10:58:11.977 DEBUG 9168 --- [nio-8080-exec-2] c.f.m.mapper.UserMapper.selectAll        : ==>  Preparing: SELECT * FROM user 
    2019-04-22 10:58:11.977 DEBUG 9168 --- [nio-8080-exec-2] c.f.m.mapper.UserMapper.selectAll        : ==> Parameters: 
    2019-04-22 10:58:11.979 DEBUG 9168 --- [nio-8080-exec-2] c.f.m.mapper.UserMapper.selectAll        : <==      Total: 2
    

    查询资料得出原因,只有同一个事务中的查询MyBatis的一级缓存才生效,加上@Transactional执行代码,结果只进行了一次查询:

    2019-04-22 11:02:09.818 DEBUG 9168 --- [nio-8080-exec-1] c.f.m.mapper.UserMapper.selectAll        : ==>  Preparing: SELECT * FROM user 
    2019-04-22 11:02:09.819 DEBUG 9168 --- [nio-8080-exec-1] c.f.m.mapper.UserMapper.selectAll        : ==> Parameters: 
    2019-04-22 11:02:09.820 DEBUG 9168 --- [nio-8080-exec-1] c.f.m.mapper.UserMapper.selectAll        : <==      Total: 2
    
    

    1.2 二级缓存

    MyBatis的二级缓存是基于Mapper级别的,也就是说多个SqlSession去使用某个Mapper的查询语句时,得到的缓存数据是可共用的。同一级缓存一样,有修改操作就会刷新缓存。二级缓存需要在mapper.xml文件中加入缓存配置:

    <cache eviction="LRU" flushInterval="60000" size="512"  readOnly="true"/>
    

    eviction:收回策略

    1. LRU – 最近最少使用的:移除最长时间不被使用的对象。 (默认)
    2. FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
    3. SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
    4. WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

    flushInterval:缓存时间
    size:存储大小,单位引用

    去掉事务代码进行测试:

    @GetMapping("/list")
    	public List<User> getAllUser() {
    		List<User> users = userMapper.selectAll();
    		List<User> users1 = userMapper.selectAll();
    		return users;
    	}
    

    结果发现第一次查询连接数据库,之后都是直接获取缓存结果:

    2019-04-22 11:32:13.017 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.selectAll        : ==>  Preparing: SELECT * FROM user 
    2019-04-22 11:32:13.017 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.selectAll        : ==> Parameters: 
    2019-04-22 11:32:13.019 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.selectAll        : <==      Total: 3
    2019-04-22 11:32:13.020 DEBUG 12616 --- [nio-8080-exec-7] c.freesky.mybatistest.mapper.UserMapper  : Cache Hit Ratio [com.freesky.mybatistest.mapper.UserMapper]: 0.6666666666666666
    2019-04-22 11:32:18.706 DEBUG 12616 --- [nio-8080-exec-9] c.freesky.mybatistest.mapper.UserMapper  : Cache Hit Ratio [com.freesky.mybatistest.mapper.UserMapper]: 0.7142857142857143
    2019-04-22 11:32:18.707 DEBUG 12616 --- [nio-8080-exec-9] c.freesky.mybatistest.mapper.UserMapper  : Cache Hit Ratio [com.freesky.mybatistest.mapper.UserMapper]: 0.75
    2019-04-22 11:32:20.292 DEBUG 12616 --- [nio-8080-exec-1] c.freesky.mybatistest.mapper.UserMapper  : Cache Hit Ratio [com.freesky.mybatistest.mapper.UserMapper]: 0.7777777777777778
    2019-04-22 11:32:20.292 DEBUG 12616 --- [nio-8080-exec-1] c.freesky.mybatistest.mapper.UserMapper  : Cache Hit Ratio [com.freesky.mybatistest.mapper.UserMapper]: 0.8
    

    更新测试:

    @GetMapping("/list1")
    public List<User> getAllUser1() {
    	//更新
    	userMapper.updateById(3L, "新名字");
    	return   userMapper.selectAll();
    }
    

    结果发现更新之后需要重新连接数据库进行查询:

    2019-04-22 11:34:15.647 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.updateById       : ==>  Preparing: UPDATE user SET name = ? WHERE id = ? 
    2019-04-22 11:34:15.648 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.updateById       : ==> Parameters: 新名字(String), 3(Long)
    2019-04-22 11:34:15.704 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.updateById       : <==    Updates: 1
    2019-04-22 11:34:15.705 DEBUG 12616 --- [nio-8080-exec-7] c.freesky.mybatistest.mapper.UserMapper  : Cache Hit Ratio [com.freesky.mybatistest.mapper.UserMapper]: 0.6666666666666666
    2019-04-22 11:34:15.705 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.selectAll        : ==>  Preparing: SELECT * FROM user 
    2019-04-22 11:34:15.705 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.selectAll        : ==> Parameters: 
    2019-04-22 11:34:15.706 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.selectAll        : <==      Total: 3
    
    只有把命运掌握在自己手中,从今天起开始努力,即使暂时看不到希望,也要相信自己。因为比你牛几倍的人,依然在努力。
  • 相关阅读:
    noi 2011 noi嘉年华 动态规划
    最小乘积生成树
    noi 2009 二叉查找树 动态规划
    noi 2010 超级钢琴 划分树
    noi 2011 阿狸的打字机 AC自动机
    noi 2009 变换序列 贪心
    poj 3659 Cell Phone Network 动态规划
    noi 2010 航空管制 贪心
    IDEA14下配置SVN
    在SpringMVC框架下建立Web项目时web.xml到底该写些什么呢?
  • 原文地址:https://www.cnblogs.com/freesky168/p/14358189.html
Copyright © 2011-2022 走看看