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
    
    只有把命运掌握在自己手中,从今天起开始努力,即使暂时看不到希望,也要相信自己。因为比你牛几倍的人,依然在努力。
  • 相关阅读:
    MUI DtPicker 显示自定义日期
    Windows10更新后,远程桌面无法登录服务器 提示远程桌面协议 CredSSP 出现漏洞
    微信Access Token 缓存方法
    在Windows7/8/10上,安装IIS
    启明星系统微信接口配置
    c#使用QQ邮箱的SSL收发邮件
    使用ASP.NET+Jquery DataTables的服务器分页
    总是容易忘记:enum、int、string之间的快速转换
    Chrome浏览器导出pdf时,隐藏链接HREF
    SQL Builder 1.04
  • 原文地址:https://www.cnblogs.com/freesky168/p/14358189.html
Copyright © 2011-2022 走看看