8.Hibernate性能优化
性能优化
1.注意session.clear() 的运用,尤其在不断分页的时候
a) 在一个大集合中进行遍历,遍历msg,取出其中额含有敏感字样的对象
b) 另外一种形式的内存泄漏( //面试题:Java有内存泄漏吗?语法级别没有,但是可由java引起,例如:连接池不关闭,或io读取后不关闭)
2.1+N 问题(典型的面试题)
举例:当存在多对一关系时,多的一方默认是可以取出一的一方的
@ManyToOne 中 默认为fetch=FetchType.Eager
当load多的一方时,也会加载一的哪一方,会造成执行不必要的SQL语句
解决办法,以下几种:
a) @ManyToOne(fetch=FetchType.LAZY)
//当多对一(@ManyToOne)已经设定属性" fetch=FetchType.LAZY "时
//只有当需要时(如:t.getCategory().getName()时)才会去获取关联表中数据 可以解决N+1问题
b) @BatchSize
//在与查询表(此例中为Topic类)关联的表类(此例中为Category类)头处加@BatchSize(size=5)
//表示每次可查出5条记录 从而减少了select语句的个数
c) join fetch
//修改hql语句为--" from Topic t left join fetch t.category c
d) QBC
//原理和上面那条是一样的,使用QBC的 createCriteria(*.class)执行查询 也可避免N+1问题
3.list 和 iterate 不同之处( //主要为了面试)
a) list 取出表中所有数据构成对象
b) iterate 先取ID,等用到的时候再根据ID 来取对象
c) session 中list 第二次发出,仍回到数据库查询
d)iterate 第二次,会先去找 session 缓存
Hibernate 缓存机制
前面Hibernate中持久化对象的三种状态有提到,处于Persistent状态的对象的标志是 缓存中也有这个对象
缓存中类似于一个一个的键值对,key 为 id,然后value为这个缓存的对象
当想要对该对象进行读写时,会先去查缓存,
/*一级缓存和二级缓存和查询缓存*/
一级缓存:session级的缓存,每个session拥有自己的session缓存,不同session的session缓存不能共享
二级缓存:sessionFactory级的缓存,所有的session都可以去访问二级缓存
查询缓存:相同的SQL语句只执行一次
当缓存的对象 1.经常被访问 2.不会经常改动 3.数量不大 时使用二级缓存
打开二级缓存(两步):
1.在 hibernate.cfg.xml中设定:
<property name= "cache.use_second_level_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
2.@Cache 注解 (由hibernate扩展提供)
@Cache (usage=CacheConcurrencyStrategy.READ_WRITE)
(为某个类开启二级缓存,针对该类的对象进行的 读写操作,会创建二级缓存)
注:使用EhCache 二级缓存需要导入 ehcache-1.2.3.jar 及 commons-logging-1.0.4.jar 包
注:
1.load 默认使用二级缓存,iterate 默认使用二级缓存
2.list 默认往二级缓存加数据,但是查询的时候不使用
意思是:session.createQuery("from Category").list(); 会将查出来的数据加到缓存中,但是不会去缓存中查询
3.可以使用<property name="hibernate.cache.use_query_cache">true</property>来打开查询缓存,默认为关闭,
查询缓存来标识某个查询使用缓存,当执行同一条SQL语句时,就不会再去数据库找,也是从缓存中去找该语句
在打开了查询缓存之后,需要注意,调用query.list()操作之前,必须显示调用query.setCacheable(true)
例如:session.createQuery("from Category").setCacheable(true).list();
注:查询缓存只对query.list()起作用,query.iterate不起作用,也就是query.iterate不使用
4.缓存算法(新的缓存对象要进来,怎么替换):(面试)
LRU LFU FIFO
1.Least Recently Used 最近最少使用的被替换
2.Least Frequently Used 命中率高低 使用频率最低的被替换
3.First In First Out 按顺序替换
在ehcache.xml中配置 memoryStoreEvictionPolicy="LRU"
事务并发处理
a) 事务:ACID
Atomic Consistency Itegrity Durability
b) 事务并发时可能出现的问题:
1.脏读 (读到了另一个事务在处理中还未提交的数据)
2.不可重复读 (在事务A的执行过程中,事务B进行了开启,对列中的数据进行修改和提交,
导致事务A在事务B执行前读取的数据和事务B执行后读取的数据不一致)
3.虚读 (在查询某一条件的数据时,开始查询后,别人又加入或删除某些数据,再读取时与原来的数据不一样了,
和 不可重复读 类似,不过不可重复读针对的列里面数据的修改,而幻读针对的是列整体的增删)
c) 数据库事务的隔离级别
1------read-uncommitted
2------read-committed
4------repeatable read
8------serializable
前面的数字为Hibernate的事务隔离级别对应的数字
为什么要使用1 2 4 8 而不是 1 2 3 4
1=0000 2=0010 4=0100 8=1000 位运算效率高
read-uncommitted(允许读取未提交的数据) 会出现dirty read, phantom-read, non-repeatable read 问题
read-commited(读取已提交的数据 项目中一般都使用这个)不会出现dirty read,
因为只有另一个事务提交才会读出来结果,但仍然会出现 non-repeatable read 和 phantom-read
/*使用read-commited机制可用悲观锁 乐观锁来解决non-repeatable read 和 phantom-read问题*/
repeatable read(事务执行中其他事务无法执行修改或插入操作 较安全)
serializable 解决一切问题(顺序执行事务 不并发,实际中很少用)
如何设定Hibernate 的事务隔离级别(使用hibernate.connection.isolation配置 取值1、2、4、8)
1.hibernate.connection.isolation = 2 (如果不设 默认依赖数据库本身的级别)
2.用悲观锁解决repeatable read的问题(依赖于数据库的锁(select... for update))
hibernate使用Load进行悲观锁加锁 session.load(Inventory.class, 1, LockMode.UPGRADE); 在生成select语句时,会加上for update 进行使用悲观锁
a)LockMode.None 无锁的机制,Transaction结束时,切换到此模式
b)LockMode.read 在査询的时候hibernate会自动获取锁
c)LockMode.write insert update hibernate 会自动获取锁
d)以上3种锁的模式,是hibernate内部使用的(不需要设)
e)LockMode.UPGRADE_NOWAIT 是 ORACLE 支持的锁的方式
3.乐观锁(其实不是锁,是一种冲突检测机制)
实体类中增加version属性 (数据库也会对应生成该字段初始值为0),并在其get方法前加入 @Version 注解
则在操作的过程中每更新一次该行数据则version值 加 1,即可在事务提交前判断该数据是否被其他事务修改过
(提交事务时,通过对比内存中的version值和数据库中的version值)
注:乐观和悲观的区别:
1.悲观锁比较悲观,觉得会有并发的情况发生,所以提前加了一把锁,
2.乐观锁比较乐观,不着急加锁,而是先判断是否出现了并发访问的情况,如果出现了,再做相应的处理
8.Hibernate性能优化的更多相关文章
- Hibernate性能优化之EHCache缓存
像Hibernate这种ORM框架,相较于JDBC操作,需要有更复杂的机制来实现映射.对象状态管理等,因此在性能和效率上有一定的损耗. 在保证避免映射产生低效的SQL操作外,缓存是提升Hibernat ...
- Hibernate性能优化之SessionFactory重用
Hibernate优化的方式有很多,如缓存.延迟加载以及与SQL合理映射,通过对SessionFactory使用的优化是最基础的. SessionFactory负责创建Session实例,Sessio ...
- Hibernate性能优化
1.性能是与具体的项目挂钩的,并不是对于A项目某种优化方法好就适用于B项目.性能需要不断的测试检验出来的.....(废话) 2.session.clear()方法的使用,通常session是有缓存的 ...
- 第七章 Hibernate性能优化
一对一关联 实体类关系 一对多 多对多 一对一 Hibernate提供了两种映射一对一关联关系的方式:按照外键映射和按照主键映射.下面以员工账号和员工档案表为例,介绍这两种映射方式,并使用这两种映射方 ...
- Hibernate 性能优化一对一关联映射
概述: hibernate提供了两种映射一对一关联的方式:按照外键映射和按照主键映射. 下面以员工账号和员工档案为例 ,介绍两种映射方式,并使用这两种映射方式分别完成以下持久化操作: (1)保存员工档 ...
- Hibernate 性能优化之一级缓存
1.一级缓存的生命周期 一级缓存在session中存放,只要打开session,一级缓存就存在了,当session关闭的时候,一级缓存就不存在了 2.一级缓存是依赖于谁存在的 ...
- 关于Hibernate性能优化之 FetchType=Lazy时查询数据
当表A和表B一对多的关系 对于A和B的实体类,设置FetchType=EAGER时,取A表数据,对应B表的数据都会跟着一起加载,优点不用进行二次查询.缺点是严重影响数据查询的访问时间. 解决办法Fet ...
- hibernate 性能优化之 1+N 问题
1. 注意 session.clear()的运用,尤其在不断分页查询的时候 a) 在一个大集合中进行遍历,遍历 msg,去除其中的含有敏感字样的对象 b) 另外一种形式的内存泄漏 面试题:Java 有 ...
- Hibernate 性能优化之查询缓存
查询缓存是建立在二级缓存基础之上的,所以与二级缓存特性相似,是共享的,适合修改不是很频繁的数据 查询缓存不是默认开启的,需要设置 1.在cfg文件中配置 <property name= ...
随机推荐
- 基于layui的表格异步删除,ajax的简单运用
h话不多说,看图,点击删除,出现确认框,然后点击确认删除,直接删除数据, 因为是基于面向过程的,没有用php框架写,所以有3个文件: 第一个文件:data.php:用于从数据库中获取数据 <?p ...
- wpf相关好资源
Textbox Drag/Drop in WPFhttp://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in-WPF.aspx Odys ...
- CPU-内存-IO-网络调优
一.关于CPU 中央处理器调优 1. CPU处理方式: 批处理,顺序处理请求.(切换次数少,吞吐量大) 分时处理.(如同"独占",吞吐量小)(时间片,把请求分为一个一个的时间片,一 ...
- mysql中update的low_priority解决并发问题
在处理访客信息更新是遇到了大并发的问题,low_priority,低优先级,可以让并发没那么占CPU,对于低配VPS来说,作用还是很大的.UPDATE [LOW_PRIORITY] tbl_name ...
- 《Java语言程序设计》第三讲类与对象“动手动脑”
一.以下代码为何无法通过编译?哪儿出错了? 答: 如果类提供了一个自定义的构造方法,将导致系统不再提供默认构造方法. 二. (1)以下代码输出结果是什么? package xy; public cla ...
- 【OpenCV】轮廓的特征矩Moment
opencv中的矩主要包括以下几种:空间矩,中心矩和中心归一化矩. class Moments { public: ...... // 空间矩 double m00, m10, m01, m20, m ...
- ipad3 修理记录
1,左下角 有视频线 2,右下角 有WIFI线
- python手撸桌面计算器
网上有一些许多关于计算器的源码,但我似乎不太care 一直寻思着自己手撸一个才有意思,于是这就开始了 实现功能: 1.基本的两个数 +-x÷ 运算以及取反,百分之,平方等 2.支持连续运算 3.暂不支 ...
- Nginx的负载均衡和项目部署
nginx的作用 Nginx是一款自由的.开源的.高性能的HTTP服务器和反向代理服务器:同时也是一个IMAP.POP3.SMTP代理服务器:Nginx可以作为一个HTTP服务器进行网站的发布处理,另 ...
- [转帖]prometheus数据采集exporter全家桶
prometheus数据采集exporter全家桶 Rainbowhhy1人评论2731人阅读2019-04-06 15:38:32 https://blog.51cto.com/13053917/2 ...