`
cheng.xinwei
  • 浏览: 78399 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

【mybatis】多次查询缓存的问题

阅读更多
    最近在使用mybatis的过程中,发现一个问题。如果在同一个事物中,多次同一个查询sql在mybatis的执行过程中,只会查询一次数据库,后几次所返回的对象是mybatis在在内部做了缓存。

   
         Property property = this.findByPropertyId("123");
    	property.setPropertyId(null);;
    	property = this.findByPropertyId("123");
    	System.out.println(property.getPropertyId());
    


   
    以上的代码,打印的结果为 null , 但是我们所期望的可能是 123 , 我不知道这是mybatis的一个bug还是故意这样去设计的.mybatis在执行查询语句的时候,会在本地做一份缓存信息.在BaseExecutor类中:
   


   
    private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
    List<E> list;
    localCache.putObject(key, EXECUTION_PLACEHOLDER);
    try {
      list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
    } finally {
      localCache.removeObject(key);
    }
    localCache.putObject(key, list);
    if (ms.getStatementType() == StatementType.CALLABLE) {
      localOutputParameterCache.putObject(key, parameter);
    }
    return list;
  }
    


   
    可以看到在queryFromDatabase方法中,查询数据库返回结果之后,mybatis编制了一个cachekey的对象,作为key,返回结果作为value,放入了缓存当中(这个地方没有使用拷贝的函数,所以只要外部修改了值,内部缓存中的值信息也会被修改)

    之后再下次查询的时候,会依据一个判断,是否需要执行缓存信息,同样是在BaseExecutor类中.
   


  @SuppressWarnings("unchecked")
  public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
    ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());
    if (closed) throw new ExecutorException("Executor was closed.");
    if (queryStack == 0 && ms.isFlushCacheRequired()) {
      clearLocalCache();
    }
    List<E> list;
    try {
      queryStack++;
      list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;
      if (list != null) {
        handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
      } else {
        list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
      }
    } finally {
      queryStack--;
    }
    if (queryStack == 0) {
      for (DeferredLoad deferredLoad : deferredLoads) {
        deferredLoad.load();
      }
      deferredLoads.clear(); // issue #601
      if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
        clearLocalCache(); // issue #482
      }
    }
    return list;
  }
     


    看到mybatis判断了 ms.isFlushCacheRequired() 的返回数据,如果为 true 会执行 clearLocalCache 方法,清空缓存信息。如果缓存中获取不到的话,才会继续去查询数据库。
可以从   list = resultHandler == null ? (List<E>) localCache.getObject(key) : null; 代码中看出。

   所以当第一次查询放入缓存之后,在外部修改了任何一个值之后,mybatis内部缓存的值也会被修改,而且下次查询不会查询数据库,直接返回缓存中被修改过的值


    ms.isFlushCacheRequired() 这段代码的判断是基于了一个MappedStatement 类中的flushCacheRequired 的属性做判断的。flushCacheRequired  变量可以通过注解的方式和xml的方式来配置
   
    1.注解:注解的方式是通过 @Options 注解中 flushCache 的配置
    2.配置文件:xml中每一个select 都可以设置 flushCache 的属性

    flushCache 设置成true之后,本sql的每次查询都会清空缓存后在执行。
   

  
   
0
0
分享到:
评论

相关推荐

    MyBatis 二级缓存 关联刷新实现

    也就是针对于同一事务,多次执行同一Mapper的相同查询方法,第一查询后,MyBatis会将查询结果放入缓存,在中间不涉及相应Mapper的数据更新(Insert,Update和Delete)操作的情况下,后续的查询将会从缓存中获取,而...

    SmartSql:SmartSql = C#中的MyBatis + .NET Core +缓存(内存| Redis)+ RW拆分+ PropertyChangedTrack +动态存储库+ InvokeSync +诊断

    SmartSql() 总览 SmartSql = MyBatis +缓存(内存| Redis)+ R / W拆分+动态存储库+诊断... 简单,高效,高性能,可扩展,监视,逐步开发... 经过数次微服务验证后,SmartSql在生产环境中已经脱离正式开源两年多了。

    spring-boot mybaits shiro redis整合

    立即执行一次任务。 5、缓存和Session =========== 注解redis缓存数据,Spring-session和redis实现分布式session同步(建议按功能模块划分系统)。 6、日志 =========== logback打印日志,业务日志和调试日志...

    SSM+Redis项目整合

    1.注意修改db.properties中的数据库配置信息,...5.success.jsp页面中可以测试Redis是否配置成功,多次点击按钮查询观察select的执行情况 6.压缩包里有三个demo1,分别是mybatis二级缓存版、spring4.0版、spring3.0版。

    基于SpringBoot+Mybatis开发的主从架构的Steam商城,详情请看README+源代码+文档说明+数据库sql

    * 客户端不断轮询缓存,查询到对应的秒杀订单,则秒杀成功 秒杀的一些优化(借鉴了网上的思路): * 增加了秒杀的随机路径,防刷 * 在秒杀开始前需要验证码输入,延缓压力 * 利用redis的缓存,限制每个用户的每...

    SpringBoot笔记-下篇.pdf

    次调用直接从缓存中获取。 • 使用Spring缓存抽象时我们需要关注以下两点; 1、确定方法需要被缓存 以及他们的缓存策略 2、从缓存中读取之前缓存存储的数据 Cache 缓存接口,定义缓存操作。实现有:RedisCache、...

    mysql数据优化详细教程

    因此可以部分数据从数据库中抽取出来放到应用端以文本方式存储, 或者使用框架(Mybatis, Hibernate)提供的一级缓存/二级缓存,或者使用redis数据库来缓存数据 。负载均衡是应用中使用非常普遍的一种优化方法,它的...

    sqltoy-orm框架系统-其他

    4、最巧妙的缓存应用,将多表关联查询尽量变成单表 5、跨数据库 6、提供行列转换(数据旋转),避免写复杂的sql或存储过程,用算法来化解对sql的高要求,同时实现数据库无关(不管是mysql还是sqlserver) 7、提供分组...

    基于java的saas多租户商城源码

    快速搭建专属电商系统,内置多租户saas等功能,方便迅速展开业务,安全便捷,框架成熟稳定便于扩展,支持二次开发定制。 环境必备 Jdk8+ Mysql5.7+ Maven Lombok(重要) 软件架构 核心框架:Spring Boot 2.4.0 安全...

    基于SpringBoot + MySQL + Redis + RabbitMQ + Guava开发的高并发商品限时秒杀系统

    充分利用缓存:秒杀商品是一个典型的读多写少的应用场景,充分利用缓存将大大提高并发量 实现技术点 1. 两次MD5加密 将用户输入的密码和固定Salt通过MD5加密生成第一次加密后的密码,再讲该密码和随机生成

    Spring_Memcached:使用与Spring集成的Memcached

    然后,您必须应用缓存机制,以避免多次数据库调用和更快的响应。一个免费的开源内存中缓存系统,可通过减少数据库负载来加速应用程序。用Spring进行Memcached 在这个项目中,您将发现spring REST应用程序中...

    Java常见面试题208道.docx

    面试题包括以下十九部分:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql...

    java快速开发平台,springboot 前后端开发框架vue 适用于制造业,物料行业、零售等,一般企业开发业务java平台

    Spring Boot、MyBatis、Vue ,内置模块如:部门管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、代码生成等。在线定时任务配置;支持集群,支持多数据源,支持分布式事务 完全响应式布局(支持电脑...

    CrapApi.v8.0.4

    CarpApi开源API接口管理系统,新版历经近100次提交修改,将hibernate替换为mybatis、调整底层结构,项目更加清晰、支持自定义首页、使用google缓存方案替换原有缓存、全新的首页、文章分类调整、支持word&pdf;...

    lamp-cloud微服务脚手架

    使用Mybatis拦截器实现对所有SQL的拦截,修改默认的Schema,从而实现多租户数据隔离的目的。 并且支持可插拔。 9、二级缓存 采用J2Cache操作缓存,第一级缓存使用内存(Caffeine),第二级缓存使用 Redis。 由于大量的...

    CrapApi.v8.0.5

    CarpApi开源API接口管理系统,新版历经近100次提交修改,将hibernate替换为mybatis、调整底层结构,项目更加清晰、支持自定义首页、使用google缓存方案替换原有缓存、全新的首页、文章分类调整、支持word&pdf;...

    java面试题20道(适合工作1~3年)(附答案).docx

    多线程创建有几种方式?GC是什么? 为什么要有GC?thorw与thows的区别? Log4j常用的四个日志级别是哪四个?优先级顺序是怎样的?拦截器和过滤器有什么区别?程序中是先执行拦截器还是过滤器?请描述Mybatis结果集中...

    通用权限系统-中台组件化

    品达通用权限系统基于SpringCloud(Hoxton.SR1) +SpringBoot(2.2.2.RELEASE) 的微服务框架,具备通用的用户管理、资源权限管理、网关统一鉴权、XSS防跨站攻击等多个模块,支持多业务系统并行开发,支持多服务并行开发...

    Java毕业设计-基于ssm框架开发的Java语言校园快递代取系统的设计与实现+jsp-毕业论文(附源代码).rar

    同时,我们也注重系统的性能和安全性,通过优化数据库查询、使用缓存技术等手段提升系统响应速度,并通过加密传输、权限验证等方式保障用户数据的安全。 在实现方面,我们充分利用了SSM框架的优势,通过Spring实现...

    RuoYi若依管理系统最新版 基于SpringBoot的权限管理系统

    RuoYi是一个后台管理系统,基于经典技术组合(Spring Boot、Apache Shiro、MyBatis、Thymeleaf)主要目的让开发者注重专注业务,降低技术难度,从而节省人力成本,缩短项目周期,提高软件安全质量。 本地版本为截止...

Global site tag (gtag.js) - Google Analytics