二级缓存

Spring如何解决循环依赖,你真的懂了?

对着背影说爱祢 提交于 2020-04-07 20:58:08
导读 前几天发表的文章 SpringBoot多数据源动态切换 和 SpringBoot整合多数据源的巨坑 中,提到了一个坑就是动态数据源添加@Primary接口就会造成循环依赖异常,如下图: 这个就是典型的构造器依赖,详情请看上面两篇文章,这里不再详细赘述了。本篇文章将会从源码深入解析Spring是如何解决循环依赖的?为什么不能解决构造器的循环依赖? 什么是循环依赖 简单的说就是A依赖B,B依赖C,C依赖A这样就构成了循环依赖。 循环依赖分为构造器依赖和属性依赖,众所周知的是Spring能够解决属性的循环依赖(set注入)。下文将从源码角度分析Spring是如何解决属性的循环依赖。 思路 如何解决循环依赖,Spring主要的思路就是依据三级缓存,在实例化A时调用doGetBean,发现A依赖的B的实例,此时调用doGetBean去实例B,实例化的B的时候发现又依赖A,如果不解决这个循环依赖的话此时的doGetBean将会无限循环下去,导致内存溢出,程序奔溃。spring引用了一个早期对象,并且把这个"早期引用"并将其注入到容器中,让B先完成实例化,此时A就获取B的引用,完成实例化。 三级缓存 Spring能够轻松的解决属性的循环依赖正式用到了三级缓存,在 AbstractBeanFactory 中有详细的注释。 /**一级缓存,用于存放完全初始化好的 bean,从该缓存中取出的

Java面试之MyBatis

六月ゝ 毕业季﹏ 提交于 2020-03-27 16:09:52
125. MyBatis 中 #{}和 ${}的区别是什么? \#{}是预编译处理,${}是字符替换。 在使用 #{}时,MyBatis 会将 SQL 中的 #{}替换成“?”,配合 PreparedStatement 的 set 方法赋值,这样可以有效的防止 SQL 注入,保证程序的运行安全。 126. MyBatis 有几种分页方式? 分页方式:逻辑分页和物理分页。 逻辑分页: 使用 MyBatis 自带的 RowBounds 进行分页,它是一次性查询很多数据,然后在数据中再进行检索。 物理分页: 自己手写 SQL 分页或使用分页插件 PageHelper,去数据库查询指定条数的分页数据的形式。 127. RowBounds 是一次性查询全部结果吗?为什么? RowBounds 表面是在“所有”数据中检索数据,其实并非是一次性查询出所有数据,因为 MyBatis 是对 jdbc 的封装,在 jdbc 驱动中有一个 Fetch Size 的配置,它规定了每次最多从数据库查询多少条数据,假如你要查询更多数据,它会在你执行 next()的时候,去查询更多的数据。就好比你去自动取款机取 10000 元,但取款机每次最多能取 2500 元,所以你要取 4 次才能把钱取完。只是对于 jdbc 来说,当你调用 next()的时候会自动帮你完成查询工作。这样做的好处可以有效的防止内存溢出。

Mybatis(四) Mybatis缓存

瘦欲@ 提交于 2020-03-24 20:39:47
4.1 Mybatis缓存概念   缓存就是内存中的数据,常常来自对数据库查询结果的保存,使用缓存,我们可以避免频繁的与数据进行交互,进而提高响应速度。 Mybatis 也提供了对缓存的支持,分为一级缓存和二级缓存,通过下图来理解: 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession2直接的缓存区域(HashMap)是互相不影响。 二级缓存是Mapper级别的缓存,多个SqlSession去操作同一个Mapper查询的sql语句,多个sqlSession可以共用二级缓存,二级缓存是跨SqlSession的。 4.2 一级缓存 4.2.1 一级缓存案例   mybatis一级缓存是默认开启的 @Test public void firstLevelCache() throws IOException { InputStream resourceAsSteam = Resources.getResourceAsStream("sqlMapperConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsSteam);

MyBatis框架及原理分析

☆樱花仙子☆ 提交于 2020-03-23 06:40:29
文章转载自 https://www.cnblogs.com/luoxn28/p/6417892.html 感觉写的不错。 MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情: 封装JDBC操作 利用反射打通Java类与SQL语句之间的相互转换 MyBatis的主要设计目的就是让我们对执行SQL语句时对输入输出的数据管理更加方便,所以方便地写出SQL和方便地获取SQL的执行结果才是MyBatis的核心竞争力。 MyBatis的配置 MyBatis框架和其他绝大部分框架一样,需要一个配置文件,其配置文件大致如下: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <setting name="cacheEnabled" value="true"/> <setting name="lazyLoadingEnabled" value="false"/> <!--<setting name="logImpl" value="STDOUT

微服务监控平台-缓存设计

a 夏天 提交于 2020-03-20 10:29:35
一,架构图及其说明 1,UI数据:页面 2,一级缓存:内存 3,二级缓存:硬盘文件系统 4,定时任务:同步数据库与缓存中的数据 5,数据源:数据库 二,场景分析 加缓存之前的数据信息流: 浏览器发出数据请求后,服务器后端接收到数据请求,开始通过数据源连接读取各种数据后,通过业务逻辑层处理成需要的逻辑数据后返回给浏览器。浏览器更新数据模型展现数据。 三,上述场景存在的问题 1、 每次获取数据都要走相同的数据流程来获取数据,如果遇到源数据宕机、或者逻辑性能降低情况时页面效果会非常的差。 2、 每次获取到数据后都要进行相同的数据逻辑处理,浪费性能。 3、 获取到的数据可能并没有发生变化,但是每次都产生了不必要的浪费。 四,缓存方案选择 1,划分的原则:业务场景 2,常见方案:   1)一级缓存+二级缓存;   2)一级缓存; 3,实现方式:   1)一级缓存可以采用HashTable的方式来进行数据存储。不同的页面可以创建不同的HashTable对象,页面的不同信息块创建不同的Key值,将逻辑层处理好的JSON数据作为Value来存放。当信息块更新数据时,通过Key值可以直接获取到JSON数据。如果是这个页面的数据刷新则直接将HashTable的数据序列化为JSON返回即可。 2) 二级缓存基于本地文件系统,将数据序列化为JSON后写入文本文件即可。一个页面信息块一个JSON文本文件。

hibernate原理解析

北城以北 提交于 2020-03-19 19:55:59
1.hibernate的常用接口 (1) Configucation:负责加载Hibernate的配置及映射信息,启动Hibernate,根据连接到数据库的信息来创建 SessionFactory对象。 (2) SessionFactory: 初始化Hibernate,创建Session对象。他是线程安全的,通常采用单子模式创建此对象。 (3)Session :负责保存·修改·删除·查询·加载对象,这个session不是线程安全的,使用Threadlocal来得到session (相当于创建了一个副本)。 (4)Transaction: 事务处理 开启事务的方法 Transaction tx= session.beginTransaction(); 提交事务 tx.commit(); (5) Query和Criteria:Query是执行数据库查询,Query接口包装了一个HQL语句,HQL语句是面向对象的,它引用类名 和属性名, 而不是表名和字段名。Criteria完全封装了基于字符串形式的查询语句,比Query接口更加面向对象,擅长 动态查询。 2.hibernate体系结构 3.hibernate的工作原理 (1)hibernate如何连接数据库? 配置文件Hibernate.cfg.xml文件中定义了和数据库进行连接的信息,包括数据库方言.jdbc驱动.用户名

Hibernate学习之面试问题汇总

会有一股神秘感。 提交于 2020-03-18 00:47:38
1. Hibernate 的检索方式有哪些 ? ① 导航对象图检索 ② OID检索 ③ HQL检索 ④ QBC检索 ⑤ 本地SQL检索 2. 在 Hibernate 中 Java 对象的状态有哪些 ? ①. 临时状态(transient):不处于 Session 的缓存中,OID 为 null 或等于 id 的 unsaved-value 属性值 ②. 持久化状态(persistent):加入到 Session 的缓存中。 ③. 游离状态(detached):已经被持久化,但不再处于 Session 的缓存中。 3. Session的清理和清空有什么区别? 清理缓存调用的是 session.flush() 方法. 而清空调用的是 session.clear() 方法. Session 清理缓存是指按照缓存中对象的状态的变化来同步更新数据库,但不清空缓存;清空是把 Session 的缓存置空, 但不同步更新数据库; 4. load()和get()的区别 ①:如果数据库中,没有 OID 指定的对象。通过 get方法加载,则返回的是一个null;通过load加载,则返回一个代理对象,如果后面代码如果调用对象的某个属性会抛出异常:org.hibernate.ObjectNotFoundException; ②:load 支持延迟加载,get 不支持延迟加载。 5. hibernate

mybatis与hibernate对比

拥有回忆 提交于 2020-03-12 04:54:53
第一方面:开发速度的对比 就开发速度而言,Hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简单很容易上手,但也相对简陋些。个人觉得要用好Mybatis还是首先要先理解好Hibernate。 比起两者的开发速度,不仅仅要考虑到两者的特性及性能,更要根据项目需求去考虑究竟哪一个更适合项目开发,比如:一个项目中用到的复杂查询基本没有,就是简单的增删改查,这样选择hibernate效率就很快了,因为基本的sql语句已经被封装好了,根本不需要你去写sql语句,这就节省了大量的时间,但是对于一个大型项目,复杂语句较多,这样再去选择hibernate就不是一个太好的选择,选择 mybatis 就会加快许多,而且语句的管理也比较方便。 第二方面:开发工作量的对比 Hibernate和MyBatis都有相应的代码生成工具。可以生成简单基本的DAO层方法。针对高级查询,Mybatis需要手动编写SQL语句,以及ResultMap。而Hibernate有良好的映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于业务流程。 第三方面:sql优化方面 Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。而Mybatis的SQL是手动编写的

MyBatis面试题(三)

China☆狼群 提交于 2020-03-11 02:21:38
说说对ORM的理解? 答:ORM就是所谓的对象关系映射,通过这门技术,可以让程序中的实体对象和数据库的记录做到互相映射,对象可以借此持久化到数据库记录,数据库记录也能借此转化为实体对象。 为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里? 答:Hibernate就属于全自动ORM映射工具,因为使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而 Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。 你对MyBatis的一级缓存和二级缓存有了解吗,说一下? 答:MyBatis默认只开启一级缓存,一级缓存是对同一个SqlSession起作用,在使用SqlSession第一次查询后,MyBatis会将结果缓存起来,如果下次再使用同一个SqlSession调用Mapper方法,sql的参数也完全相同,如果没有声明需要刷新,同时缓存也没有超时,那SqlSession都会取出当前缓存的数据,而不会再次发送SQL到数据库做查询。 MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能。SqlSessionFactory层面上的二级缓存默认是不开启的,二级缓存的开启需要进行配置,实现二级缓存的时候

课时11:禁用、清理二级缓存,以及整合Ehcache缓存

烈酒焚心 提交于 2020-03-10 20:56:16
.1)如何禁用二级缓存   1 在具体要关闭的mapper.xml中的select标签里面填写 <select id="selectStudentById" resultType="student" parameterType="Integer" useCache="false"> select * from student where stuno=#{stuno} </select> .2).清理:与清理缓存一级缓存相同  1 SqlSession.close()才会记录成缓存;(执行增删改会将缓存清除了;设计的原因 是为了脏数据的产生) 在二级缓存中,SqlSession.commit()不能查询自身的commit()。     SqlSession.commit()会清理一级缓存和二级缓存;但是清理二级缓存时不能查询自身的SqlSession.commit()  2 在select标签中添加flushCache="true"也可以清除缓存 .3)命中率:   1.zs:0% ===>50% ===> 66.6% ===> 75% .4)整合Ehcache二级缓存 (第三方缓存有很多种,以Ehcache为例)   1.需要导入如下三个jar包 <!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache-core