Hibernate高级应用

1.一级缓存(session里面的实体对象,存放在内存中)

☞get/load/list/iterate可以将对象放入到一级缓存中

List操作不会利用一级缓存

☞get/load/iterate可以利用一级缓存

☞flush方法将改变后的同对象持久化到数据库中

2.二级缓存

即SessionFactory级别的缓存。默认的情况下是打开的。这是一个全局缓存策略。它可以对对象的数据进行全局缓存。

一级缓存 二级缓存 缓存的是实体对象

缓存的key是ID,缓存的value是实体对象

3.查询缓存(慎用)

即对查询的结果集进行缓存处理,以便下次相同条件相同HQL的情况下可以直接从缓存中获取数据。

查询缓存的作用,是对list操作的查询结果集进行缓存!

缓存的是普通结果集

缓存的key是HQL中的语句与参数,缓存的value则:

(1)如果查询的结果为普通结果集,则缓存这些结果集

(2)如果查询的结果为实体对象,则缓存实体对象的ID列表

用查询缓存的时候,二级缓存也要启用,防止发出多条语句

我们使用list操作的时候,如果启用了查询缓存,hibernate将根据当前查询的HQL语句(及其参数值)计算出一个缓存的key值;查询结果集,将作为缓存的value值(但如果查询结果集是一个对象结果集的话,其缓存的value值是对象的ID集合,而不是对象集合本身)。

<o:p> </o:p>

可以在hibernate配置文件中添加:

true<o:p></o:p>

以便打开查询缓存。

<o:p> </o:p>

查询缓存,对对象查询,将缓存其ID列表;对普通查询,将缓存整个数据集合。所以,对于对象查询,需要配合二级缓存来使用。

<o:p> </o:p>

在打开了查询缓存之后,需要注意,调用query.list()操作之前,必须显式调用query.setCachable(true)来标识某个查询使用缓存。

4.批量抓取

(1)抓取策略,有一个对象 ,即如何获取关联的策略。

(2)什么叫批量抓取:有一批对象,想得到这批对对象的关联

(3)在many-to-one/one-to-many中设置:fetch(在hbm.xml语句中配置)

Fetch=“select” 查询抓取,通过第二条语句查询关联(这是默认值)

Fetch=“join” 连接抓取,在加载的同时通过一条外连接已经把关联的对象加载

上来了,所以设置的lazy配置失效

Fetch=“join” 对于批量抓取的时候是无效的

当Fetch="select"可以定义批量抓取策略,在对方的class映射文件中配置batch-size

即可

连接抓取(Join fetching) - Hibernate通过 在SELECT语句使用OUTER JOIN(外连接)来 获得对象的关联实例或者关联集合。 连接抓取策略可以被定义在或集合(如)标签上。这种抓取策略,对load/get操作有效。

· 如在Student的标签上设置fetch=”join”,当我们load/get一个Student的时候,其classes属性的值,将通过一个outter join连接查询来获取

· 或在Classes类的标签上设置fetch=”join”,当我们load/get一个Classes类的实例的时候,其集合数据,也是通过一个outter join连接查询来抓取

· 查询抓取(Select fetching) - 另外发送一条 SELECT 语句抓取当前对象的关联实体或集合。除非你显式的指定lazy="false"禁止 延迟抓取(lazy fetching),否则只有当你真正访问关联关系的时候,才会执行第二条select语句。 这种抓取策略,设置方法为:fetch=”select”;

· 如在set标签上设置fetch=”select”,下面的查询:List list = session.createQuery(“from Classes cls where id in (1,22)”).list();将产生如下结果:

Hibernate: select classes0_.id as id7_, classes0_.name as name7_ from T_Classes classes0_ where classes0_.id in (1 , 22)<o:p></o:p>

<o:p> </o:p>

Hibernate: select students0_.classesid as classesid1_, students0_.id as id1_, students0_.id as id8_0_, students0_.name as name8_0_, students0_.sex as sex8_0_, students0_.classesid as classesid8_0_ from T_Student students0_ where students0_.classesid=?<o:p></o:p>

<o:p> </o:p>

Hibernate: select students0_.classesid as classesid1_, students0_.id as id1_, students0_.id as id8_0_, students0_.name as name8_0_, students0_.sex as sex8_0_, students0_.classesid as classesid8_0_ from T_Student students0_ where students0_.classesid=?<o:p></o:p>

可见,总共发出:第一,查询Classes的数据;第二,因为查询结果集中有两个Classes对象,所以针对每个对象,都发出了一个查询语句以便查询其students集合的数据。<o:p></o:p>

· <o:p> </o:p>

· 子查询抓取(Subselect fetching) - 另外发送一条SELECT 语句抓取在前面查询到(或者抓取到)的所有实体对象的关联集合。除非你显式的指定lazy=“false” 禁止延迟抓取(lazy fetching),否则只有当你真正访问关联关系的时候,才会执行第二条select语句。 设置方法是:fetch=”subselect”,它只能被设置在集合映射的属性上。

· 如在set标签上设置fetch=”sebselect”,下面的查询:List list = session.createQuery(“from Classes cls where id in (1,22)”).list();在list对象中,将包含两个Classes对象的实例,假设其集合上配置lazy=”false”,我们立刻就能看到hibernate的subselect抓取策略是:

以下是hibernate生成的SQL语句:<o:p></o:p>

Hibernate: select classes0_.id as id7_, classes0_.name as name7_ from T_Classes classes0_ where classes0_.id in (1 , 22)<o:p></o:p>

<o:p> </o:p>

☞悲观锁和乐观锁

两个人同时修改用一条数据时,就会才产生数据不一致

这是我们需要用乐观锁来解决这个问题!

悲观锁:锁定一条记录,当修改成功后,对方才能修改(一直等待)

在实体bean中设置

Person p=(Person)session.get(Person.class, 1,LockOptions.UPGRADE);

缺点:当遇到多个线程的时候,会发送死锁,效率也不高(不建议使用)

乐观锁(建议使用):通过版本号约束hibernate是否更新,避免了数据更新的丢失,在实体类中加属性版本号:int versionNumber ,在对应的映射文件中添加

5.批量更新/保存

向数据库中插入1万条数据,如何提高效率?

对于在Mysql数据库中加入(oracle数据库中则不需要加入)

jdbc:mysql://localhost/hibernate?rewriteBatchedStatements=true

//25

原文:https://blog.csdn.net/javahuangfang/article/details

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值