沧州三亚菏泽经济预测自然
投稿投诉
自然科学
知识物理
化学生物
地理解释
预测理解
本质社会
人类现象
行为研究
经济政治
心理结构
关系指导
人文遗产
菏泽德阳
山西湖州
宝鸡上海
茂名内江
三亚信阳
长春北海
西安安徽
黄石烟台
沧州湛江
肇庆鹤壁
六安韶关
成都钦州

聊聊MyBatis缓存

4月8日 六壬会投稿
  本文主要内容如下:
  一、MyBatis缓存中的常用概念
  MyBatis缓存:它用来优化SQL数据库查询的,但是可能会产生脏数据。
  SqlSession:代表和数据库的一次会话,向用户提供了操作数据库的方法。
  MappedStatement:代表要发往数据库执行的指令,可以理解为是SQL的抽象表示。
  Executor:代表用来和数据库交互的执行器,接受MappedStatment作为参数。
  namespace:每个Mapper文件只能配置一个namespace,用来做Mapper文件级别的缓存共享。
  映射接口:定义了一个接口,然后里面的接口方法对应要执行SQL的操作,具体要执行的SQL语句是写在映射文件中。
  映射文件:MyBatis编写的XML文件,里面有一个或多个SQL语句,不同的语句用来映射不同的接口方法。通常来说,每一张单表都对应着一个映射文件。二、MyBatis一级缓存2。1一级缓存原理
  在一次SqlSession中(数据库会话),程序执行多次查询,且查询条件完全相同,多次查询之间程序没有其他增删改操作,则第二次及后面的查询可以从缓存中获取数据,避免走数据库。
  每个SqlSession中持有了Executor,每个Executor中有一个LocalCache。当用户发起查询时,MyBatis根据当前执行的语句生成MappedStatement,在LocalCache进行查询,如果缓存命中的话,直接返回结果给用户,如果缓存没有命中的话,查询数据库,结果写入LocalCache,最后返回结果给用户。
  LocalCache其实是一个hashmap的结构:privateMapObject,ObjectcachenewHashMapObject,Object();复制代码
  如下图所示,有两个SqlSession,分别为SqlSession1和SqlSession2,每个SqlSession中都有自己的缓存,缓存是hashmap结构,存放的键值对。
  键是SQL语句组成的Key:StatementIdOffsetLimmitSqlParams复制代码
  值是SQL查询的结果:
  2。2一级缓存配置
  在mybatisconfig。xml文件配置,namelocalCacheScope,value有两种值:SESSION和STATEMENTconfigurationsettingssettingnamelocalCacheScopevalueSESSIONsettingsconfiguration复制代码
  SESSION:开启一级缓存功能
  STATEMENT:缓存只对当前执行的这一个SQL语句有效,也就是没有用到一级缓存功能。
  首先我们通过几个考题来体验下MyBatis一级缓存。2。3一级缓存考题
  考题(1)只开启了一级缓存,下面的代码调用了三次查询操作getStudentById,请判断,下列说法正确的是?打开一个SqlSessionSqlSessionsqlSessionfactory。openSession(true);StudentMapperstudentMappersqlSession。getMapper(StudentMapper。class);根据id1查询学生信息System。out。println(studentMapper。getStudentById(1));根据id1查询学生信息System。out。println(studentMapper。getStudentById(1));根据id1查询学生信息System。out。println(studentMapper。getStudentById(1));复制代码
  答案:第一次从数据库查询到的数据,第二次和第二次从MyBatis一级缓存查询的数据。
  解答:第一次从数据库查询后,后续查询走MyBatis一级缓存
  考题(2)只开启了一级缓存,下面代码示例中,开启了一个SqlSession会话,调用了一次查询,然后对数据进行了更改,又调用了一次查询,下列关于两次查询的说法,正确的是?打开一个SqlSessionSqlSessionsqlSessionfactory。openSession(true);StudentMapperstudentMappersqlSession。getMapper(StudentMapper。class);根据id1查询学生信息System。out。println(studentMapper。getStudentById(1));插入了一条学生数据,改变了数据库System。out。println(增加了studentMapper。addStudent(buildStudent())个学生);根据id1查询学生信息System。out。println(studentMapper。getStudentById(1));sqlSession。close();复制代码
  答案:第一次从数据库查询到的数据,第二次从数据库查询的数据
  解答:第一次从数据库查询后,后续更新(包括增删改)数据库中的数据后,这条SQL语句的缓存失效了,后续查询需要重新从数据库获取数据。
  考题(3)当开启了一级缓存,下面的代码中,开启了两个SqlSession,第一个SqlSession查询了两次学生A的姓名,第二次SqlSession更新了一次学生A的姓名,请判断哪个选项符合最后的查询结果。SqlSessionsqlSession1factory。openSession(true);SqlSessionsqlSession2factory。openSession(true);StudentMapperstudentMappersqlSession1。getMapper(StudentMapper。class);StudentMapperstudentMapper2sqlSession2。getMapper(StudentMapper。class);studentMapper2。updateStudentName(B,1);System。out。println(studentMapper。getStudentById(1));System。out。println(studentMapper2。getStudentById(1));复制代码
  答案:AB复制代码
  解答:只开启一级缓存的情况下,SqlSession级别是不共享的。代码示例中,分别创建了两个SqlSession,在第一个SqlSession中查询学生A的姓名,第二个SqlSession中修改了学生A的姓名为B,SqlSession2更新了数据后,不会影响SqlSession1,所以SqlSession1查到的数据还是A。2。4MyBatis一级缓存失效的场景不同的SqlSession对应不同的一级缓存同一个SqlSession但是查询条件不同同一个SqlSession两次查询期间执行了任何一次增删改操作同一个SqlSession两次查询期间手动清空了缓存2。5MyBatis一级缓存总结MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺MyBatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为Statement一级缓存的配置中,默认是SESSION级别,即在一个MyBatis会话中执行的所有语句,都会共享这一个缓存。三、MyBatis二级缓存3。1MyBatis二级缓存概述MyBatis的二级缓存相对于一级缓存来说,实现了SqlSession之间缓存数据的共享,同时粒度更加的细,能够到namespace级别,通过Cache接口实现类不同的组合,对Cache的可控性也更强。MyBatis在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件比较苛刻。在分布式环境下,由于默认的MyBatisCache实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将MyBatis的Cache接口实现,有一定的开发成本,直接使用Redis、Memcached等分布式缓存可能成本更低,安全性也更高。3。2MyBatis二级缓存原理
  一级缓存最大的共享范围就是一个SqlSession内部,如果多个SqlSession之间需要共享缓存,则需要使用到二级缓存。
  开启二级缓存后,会使用CachingExecutor装饰Executor,进入一级缓存的查询流程前,先在CachingExecutor进行二级缓存的查询。
  二级缓存开启后,同一个namespace下的所有操作语句,都影响着同一个Cache。
  每个Mapper文件只能配置一个namespace,用来做Mapper文件级别的缓存共享。mappernamespacemapper。StudentMappermapper复制代码
  二级缓存被同一个namespace下的多个SqlSession共享,是一个全局的变量。MyBatis的二级缓存不适应用于映射文件中存在多表查询的情况。
  通常我们会为每个单表创建单独的映射文件,由于MyBatis的二级缓存是基于namespace的,多表查询语句所在的namspace无法感应到其他namespace中的语句对多表查询中涉及的表进行的修改,引发脏数据问题。3。3MyBatis缓存查询的顺序
  先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用如果二级缓存没有命中,再查询一级缓存如果一级缓存也没有命中,则查询数据库SqlSession关闭之后,一级缓存中的数据会写入二级缓存。3。4二级缓存配置
  开启二级缓存需要在mybatisconfig。xml中配置:settingnamecacheEnabledvaluetrue复制代码3。5二级缓存考题
  测试update操作是否会刷新该namespace下的二级缓存。
  开启了一级和二级缓存,通过三个SqlSession查询和更新学生张三的姓名,判断最后的输出结果是什么?SqlSessionsqlSession1factory。openSession(true);SqlSessionsqlSession2factory。openSession(true);SqlSessionsqlSession3factory。openSession(true);StudentMapperstudentMappersqlSession1。getMapper(StudentMapper。class);StudentMapperstudentMapper2sqlSession2。getMapper(StudentMapper。class);StudentMapperstudentMapper3sqlSession3。getMapper(StudentMapper。class);System。out。println(studentMapper读取数据:studentMapper。getStudentById(1));sqlSession1。commit();System。out。println(studentMapper2读取数据:studentMapper2。getStudentById(1));studentMapper3。updateStudentName(李四,1);sqlSession3。commit();System。out。println(studentMapper2读取数据:studentMapper2。getStudentById(1));复制代码
  答案:张三张三李四复制代码
  解答:三个SqlSession是共享MyBatis缓存,SqlSession2更新数据后,MyBatis的namespace缓存(StudentMapper)就失效了,SqlSession2最后是从数据库查询到的数据。四、MyBatis自定义缓存4。1MyBatis自定义缓存概述
  当MyBatis二级缓存不能满足要求时,可以使用自定义缓存替换。(较少使用)
  自定义缓存需要实现MyBatis规定的接口:org。apache。ibatis。cache。Cache。这个接口里面定义了7个方法,我们需要自己去实现对应的缓存逻辑。
  4。2整合第三方缓存EHCache
  EHCache和MyBatis已经帮我们整合好了一个自定义缓存,我们可以直接拿来用,不需要自己去实现MyBatis的org。apache。ibatis。cache。Cache接口。
  添加mybatisehcache依赖包。dependencygroupIdorg。mybatis。cachesgroupIdmybatisehcacheartifactIdversion1。2。1versiondependency复制代码
  创建EHCache的配置文件ehcache。xml。?xmlversion1。0encodingutf8?ehcachexmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:noNamespaceSchemaLocation。。configehcache。xsd!磁盘保存路径diskStorepathD:passjavaehcachedefaultCachemaxElementsInMemory1000maxElementsOnDisk10000000eternalfalseoverflowToDisktruetimeToIdleSeconds120timeToLiveSeconds120diskExpiryThreadIntervalSeconds120memoryStoreEvictionPolicyLRUdefaultCacheehcache复制代码
  设置二级缓存的类型,在xxxMapper。xml文件中设置二级缓存类型cachetypeorg。mybatis。caches。ehcache。EhcacheCache复制代码4。3EHCache配置文件说明
  五、总结
  本篇分别介绍了MyBatis一级缓存、二级缓存、自定义缓存的原理和使用,其中还穿插了4道考题来验证MyBatis缓存的功能。不足之处是MyBatis缓存源码未分析。
  参考资料:
  tech。meituan。com20180119
  原文链接:https:juejin。cnpost7156411054438744078
投诉 评论

最高水准的开放世界游戏!荒野大镖客救赎2欢迎关注网络杂物间头条号,每日分享各类游戏资源荒野大镖客2:救赎终极版RedDeadRedemption2:UltimateEdition枪战射击游戏介绍……企业陆续复工火力全开,电白制造业奏响奋进曲2023年2月7日《南方日报电白视窗》A02版报道。一瓶瓶罐头自动行驶在输送带上,经过各站点,完成检测、贴标、码垛等工序在电白区工业园广东鹰金钱海宝食品有限公司(下称海宝……可持续十问机构探索篇历史的脚步不断前行,触摸中国时代脉搏的方式,也有了更加细腻和精准的表达。从传统到创新,从煤炭到新能源,从被动跟随到自主建设,以创新、协调、绿色、开放、共享为基础的新发展理念开启……是心动的感觉!春季限定绝美花海在这里【来源:东莞市农业农村局三农快递】眼下,正值春暖花开、万物复苏的美好时节,茶山上元稻田公园的格桑花正在绽放,吸引了周边居民与多方游客前来打卡拍照,享受美好春光。在上……美国航天局和欧洲航天局公布幻影星系的新图像据美国有线电视新闻网当地时间8月30日报道,由美国国家航空航天局与欧洲航天局合作开发的哈勃望远镜和詹姆斯韦伯望远镜近日捕捉到了幻影星系的新图像,该星系的正式名称为M74,位于距……世界足坛那些让人匪夷所思的纪录,这里有5个被认为最难打破的巴萨2009年夺得六冠王,下一次出现10年后。梅西个人获得7座金球奖,下一次出现30年后。梅西1个自然年进球91个,被超越需要35年后。马拉多纳1986世界杯5进球5助攻,被超……学习淘车自驾大草原,工作和生活一样都不可怠慢我一直认为:工作是为了更好的生活,生活好了才愿意更好的工作,它们相辅相成,一样都不可怠慢。幸运的是,多年来我从事的这份二手车帮买、鉴定评估的工作和全国各地客户们的信任支持……33岁女子怀孕36周仍坚持锻炼,运动对孕妇和婴儿有哪些益处?33岁女子怀孕36周仍坚持锻炼,由于是第一胎还是双胞胎,孕早期有各种不适症状,与医生一番沟通后,坚持每周3次的力量训练和伸展练习。自律的生活习惯加之科学的运动健身,有益于……特斯拉ModelQ或在3月亮相售价大概率在10万元区间特斯拉价格一降,新能源车型的价格跌落一片。在自己没有足够强大之前,在市场中就要看人脸色,特斯拉,这条在中国车市里拼命游动的大鲶鱼,间接的影响着很多新势力车企的命运。……流感针对性药物应早服用制图:郑理文患流感如何科学服药?儿科专家支招开始时喉咙有点不舒服,很快便发高烧、咳嗽,美林吃了两次高烧都退不下来最近,家长群、小区妈妈群里,关于孩子感染流感病毒的话……经常喝黄芪水,人怎么还变瘦了?黄芪水的副作用你知道吗?黄芪是营养价值很高的中草药,是补气佳品,很多人喜欢拿它来泡水喝,补气补虚。不过有些人在喝了一段时间黄芪水后,发现自己逐渐变瘦了,就特别担心,是不是自己不适合喝黄芪水,喝出……聊聊MyBatis缓存本文主要内容如下:一、MyBatis缓存中的常用概念MyBatis缓存:它用来优化SQL数据库查询的,但是可能会产生脏数据。SqlSession:代表和数据库……
上周4家创新医疗器械公司完成融资,聚焦罕见病康复等领域新进展!上海交大发现可杀伤多种病原细菌和真菌的T6SS系统瑞幸椰风灵感拿铁好喝吗瑞幸椰风灵感拿铁多少钱一杯如何实现灵活就业人员应保尽保历经波折重回正轨,韵达快递为何被评级至强推?把握科学内涵解决实际问题中国女排3比1胜韩国!送给韩国12连败,背后还有这些故事年度镇中心小学党建工作汇报露营这么干?不行!早上斯坦福上课晚上看时装秀,谷爱凌新装扮出炉,这脸谁不沦陷?冬吃萝卜好处多推荐三种白萝卜的养生吃法官方!辽篮迎今夏首笔补强,宏远或中产续约徐杰,郭艾伦去留成疑

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找