• 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
    
    只有把命运掌握在自己手中,从今天起开始努力,即使暂时看不到希望,也要相信自己。因为比你牛几倍的人,依然在努力。
  • 相关阅读:
    .net core 3.1 过滤器(Filter) 和中间件和AOP面向切面拦截器
    socket通信框架——boost asio
    远程过程调用框架——gRPC
    数据序列化工具——flatbuffer
    springboot项目启动----8080端口被占用排雷经过
    如何配置HOSTS文件
    使用线程Callable实现分段获取一个url连接的资源数据
    Socket网络编程课件
    (6)优化TCP编写 服务器端同时支持多个客户端同时访问
    SpringBoot配置属性之Security
  • 原文地址:https://www.cnblogs.com/freesky168/p/14358189.html
Copyright © 2020-2023  润新知