hibernate 性能
缓存
缓存就是数据库数据在内存中的临时容器;
位于数据库和数据库访问层中间
ORm查询数据时会首先根据自身的缓存管理策略,在缓存中查找相关数据,如发现所需要数据,则直接将此数据作为结果加以利用。
避免数据库调用性能的开销
相对内存操作而言,数据库调用是一个代价高昂的过程。
当Session的save()方法持久化一个Customer对象时,对象被加入到session的缓存,即使引用设置为null了,只要缓存还没有清空,再调用时就不会再进行sql操作.
如果一个引用,例如 Customer c = session.get(xx,1),c这个引用还在指着对应的那个对象,那么即使session关闭了,该对象依旧还能在程序中使用,只是不能使用session的增删改查动作了。此时c为游离态。假如c中有延迟加载的对象或属性或集合,也不能再访问,会报空指针或者session is closed
session.save();//save()方法并不立即执行,只有在清理缓存时才会执行
session.flush();//真正的执行insert语句
flush(),立即执行语句
session.delete()能使一个持久化对象或游离对象变成临时状态
对象在session中有几种状态
- 瞬时(临时)状态:对象刚被new出来,实例化出来,还没有session对其进行持久操作
特征:刚new出来,数据库中没有相应记录
- 持久化状态:已经被session执行持久化save(),并且加入到session的缓存中,处于持久化状态的对象呗称为持久化对象:
特征:oid不为null;
在Session的缓存中。
数据库中有相关记录;
session清理缓存时,会根据持久化对象的属性变化,来同步更新数据库;
save()方法会让对象转变为持久化
load(),get()方法返回的对象总是处于持久化状态
Query的 list()中存放的都是持久化对象;
update(),saveOrUpdate和lock()方法使游离对象转变为持久化对象;
当一个持久化对象关联一个临时对象,在允许级联保存情况下,session在清理缓存时也会把这个临时对象转变为持久化对象;
- 删除状态:不再处于Session中,并且session已经计划将其从数据库中删除delete();(一般可以为三个状态,这个状态通俗情况下没有考虑,也可以将其算在瞬时态中)
特征:1.oid不为null;
2.被一个session从缓存中删除
3.被删除对象和数据库中相关记录对应
4.session已经准备要将其删除
5.session在清理缓存是,会执行Sql delete语句,删除数据库中的响应记录
6.一般情况下,应用程序不应该再使用被删除对象
删除状态的进入:
1.在配置文件中 hibernate.use_identifier_rollbake属性取默认值 false,情况下,delete()方法把持久化对象及游离对象转变为删除对象
2.级联删除情况下,删除持久化对象A,会级联删除持久化对象B
- 游离状态:已经被持久化,但不再处于Session的缓存中
特征: oid不为null
不在session的缓存中
游离对象是由持久化对象转变过来的,因此在数据库中可能还存在与它对相应的记录
进入:
session.close()
clear()
evict(该对象)
缓存
缓存分类:
一级缓存:在当前事务范围内的数据缓存(session)
事务级缓存基于session的生命周期实现。 (缓存到session里面),如果每次都打开一个新的session,则每次都要调用书库、。一级缓存靠id。
clear:清空session中缓存的所有对象。
二级缓存:
需要配置 缓存使用策略,有readOnly read-write;
可以在总配置中使用,也可以在单独的对象映射中使用;
还有一些其他配置
<class-cache usage="read-write" class="xxxx"/>
EhCache二级缓存插件的使用配置
<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.use_query_cache">true</property>
<!--设置放入缓存的对象-->
<class-cache usage="read-only" class="com.wang.model.User" />
针对列表查询,将查询结果放入缓存为
session.createQuery().setCacheable(true).list;
注意,从缓存里面取也是使用setCacheable;
session.flush()使hibernet李可根据对象的状态变化同步更新数据库,从而立即执行相关的update语句;
放入缓存中的数据:(防止并发问题)
很少被修改的数据
不是很重要的,允许出现偶尔的并发问题
不会被并发访问的数据
参考数据
像以下数据不适合放入缓存
- 经常被修改的数据
- 财务数据,绝对不允许出现并发问题
- 与其他应用共享的数据,如果其他应用修改了数据库中的数据,Hibernate无法自动保证第二级缓存中的数据与数据库保持一致
延迟加载(抓取策略)
列表的延迟加载,可以在访问一个对象的某个集合的时候,调用这个集合的时候才进行查询。
不用就不查,单对象(load方法)
session = sessionFactory.openSesssion(),
得到的session是一个新的session;
几种方法:
改用lazy=true,延迟加载,访问集合的属性才开始加载, 使用false,把所有的都提出来
在session关闭之前先把所有内容读取一次。
每读一个xxx对象,都自动装载好该对象的所有属性。
from xxx left(inner) join fetch xxx.set
实体对象的延迟加载
集合的延迟加载
调用延迟加载的对象中的集合属性;
Hibernate.initialize(Pet)
属性的延迟加载
访问才加载,使用比较麻烦。
session接口的使用
save(),persist()
session.save();//save()方法并不立即执行,只有在清理缓存时才会执行,如果在save()方法之后,又修改持久化对象的属性,会是的session在清理缓存时,额外执行SQL update语句
持久化对象的OID不允许随意修改
代理主键:数据库来掌控主键的自增长和主键的设置
increment;identity;
session的 save()方法保存游离对象是不符合持久化规范的操作
因为一个同样的对象如果在两个session实例中执行save(),那么数据库中会添加两条一样的数据,但是两者的id不同,造成数据库冗余;
persist(),不保证立即为持久化对象的OID赋值,而是有可能在清理缓存时才为oid赋值,如果在事务以外调用该方法,那么该方法并不会执行sql插入操作,而save()不管是在事物内还是外,都会执行;
get()方法,没有延迟加载,适用于访问它的各个属性;
load()方法,采取延迟加载;适用于为了删除它,或者为了建立别的对象的关联关系,
update(),只有在清理缓存时才会执行,因为即使多次修改对象属性,但是在清理缓存时只会执行一次update语句
设置仅当修改了customer对象的属性时才执行update语句,可以修改 select_before_update = “true”;该属性位于class标签中 ;如果java对象的属性不会经常变化。
当缓存中已经有了oid为1的对象,那么update()就不能再关联另一个oid额外1的对象
saveOrUpdate();
临时对象执行save,游离对象执行update;
临时对象一下:
oid为null;
version版本控制属性值为null;
id设置了unsaved-value属性,并且java对象的oid取值与这个属性值匹配;
如果一个id取值为0,那么就会被认为是临时对象
merge(临时或者游戏对象);
能把一个游戏对象的属性赋值到一个持久化对象中;
把值类型的属性都复制了了。
replicate(),能把一个数据库中的对象赋值到另外一个数据库中;
将一个sessionFacotry1中的对象复制到sessionFactory2 中
复制模式
ReplicationMode.IGNORE,OVERWRITE,EXCEPTION,LATEST_VERSION
本文详细介绍了Hibernate性能优化,重点关注缓存的使用和分类,包括一级缓存和二级缓存的配置与策略。讨论了延迟加载的概念,以及如何在实际操作中应用。同时,详述了session接口的各种操作及其影响,如save()、flush()和delete()等,以及对象在session中的状态管理。
998

被折叠的 条评论
为什么被折叠?



