`
gqzyyxh
  • 浏览: 9370 次
  • 性别: Icon_minigender_1
  • 来自: 常州
文章分类
社区版块
存档分类
最新评论

Hibernate持久层操作

阅读更多
1,数据加载

1),Session.get/load
区别:(1),未发现符合条件的记录:get-->null,load-->ObjectNotFoundException。
(2),load可返回实体的代理类实例,get永远直接返回实体类。
(3),load-->内部缓存-->二级缓存-->SQL(DB),get-->内部缓存-->SQL(DB)。

Session加载实体对象时经过的过程:
内部缓存(查找数据)-->NonExists(查找查询条件)-->第二级缓存(load方法)-->Select SQL(DB)-->根据Result创建对应的数据对象-->将其数据对象纳入当前Session实体管理容器(内部缓存)-->执行Interceptor.onLoad-->纳入二级缓存-->如果数据对象实现了LifeCycle接口,则调用数据对象的onLoad方法-->返回数据对象。

2),Session.find/iterate
Session.find()------->session.createQuery().list()-----无法利用缓存,它对缓存只写不读。
Session.iterate()---->session.createQuery().iterate()-----可以充分利用缓存。
-------基于充分利用缓存以提升性能上的考量。
内存使用上的考虑:对海量数据进行操作,find方法一次获得所有的记录并将其读入内存-->内存消耗甚至OutOfMemoryError。
解决方案之一:逐条对记录进行处理,将内存消耗保持在可以接受的范围之内。
String hql = "from TUser where age > ?";
Iterator it = session.iterate(hql,new Integer(18),Hibernate.INTEGER);
while(it.hasNext()){
TUser user = (TUser)it.next();
session.evict(user);//将对象从一级缓存中移除
sessionFactory.evict(TUser.class,user.getId());//将对象从二级缓存中移除
}
解决方案之二:SQL或存储过程。

3),Query Cache
---中保存了之前查询操作执行过的Select SQL,以及由此查询产生的查询结果集(包括查询对象的类型和id)。

根据查询SQL--->从Query Cache中检索--->取出这个SQL的检索结果集--->根据这个结果集中对象类型及其id,从缓存中取出对赢得实体对象返回。

Query Cache只在特定的情况下产生作用:
(1),完全相同的Select SQL重复执行。
(2),在两次查询之间,此Select SQL对应的库表没有发生过改变。

<hibernate-configuration>
<session-factory>
....
<property name="hibernate.cache.use_query_cache">true</property>
....
</session-factory>
<hibernate-configuration>

String hql="from TUser where age > ?";
Query query = session,createQuery(hql).setInteger(0,20);
query.setCacheable(true);

List userList = query.list();
int len = userList.size();
for(int i=0;i<len;i++){
TUser user = (TUser)userList.get(i);
}

query = session2.createQuery(hql).setInteger(0,20);
query.setCacheable(true);//第二次查询时,也必须将Cacheable设为true

userList = query.list();
len = userList.size();
for(int i=0;i<len;i++){
TUser user = (TUser)userList.get(i);
}
看到第二次查询时,Hibernate并没有执行任何Select SQL即完成了任务,这就是Query Cache的作用。

4),延迟加载(Lazy Loading)
---为了避免在某些情况下,关联关系所带来的无谓的性能开销。---即在需要数据的时候,才真正执行数据加载操作。

Hibernate2延迟加载实现主要针对:(1),实体对象;(2),集合。
Hibernate3同时提供了属性的延迟加载功能。

(1),实体对象的延迟加载
<class ... laze="true"> ---Hibernate2中,laze属性默认为false,Hibernate3中其默认值为true。
Hibernate的代理机制:Hibernate中引入了CGLib作为代理机制实现的基础。CGLib可以在运行期动态生成Java Class,这里的代理机制,其基本实现原理就是通过由CGLib构造一个包含目标对象所有属性和方法的动态对象(相当于动态构造目标对象的一个字类)返回,并以之作为中介,为目标对象提供更多的特性。真正的TUser对象位于代理类的CGLIB$CALLBACK_0.target属性中。
-----只有当客户程序真正调用实体类的取值方法时,Hibernate才会执行数据库查询操作。

(2),集合类型的延迟加载
<set ... lazy="true">
Hibernate.initialize方法可以强制Hibernate立即加载关联对象集。
Hibernate.initialize(user.getAddresses());
session.close();
//通过Hibernare.initialize方法强制读取数据,addresses对象即可脱离session进行操作
Set hset = user.getAddresses();
TAddress addr = (TAddress)hset.toArray()[0];

(3),属性的延迟加载
<property ... lazy="true">
与实体和集合类型的延迟加载不同,Hibernate3属性延迟加载机制在配置之外,还需要借助类增强器对二进制Class文件进行强化处理。

5),数据保存

Session.save方法用于实体对象到数据库的持久化操作。
包含步骤:在Session内部缓存中寻找待保存对象-->lifecycle(onSave())-->Validatable(validate())-->Interceptor.onSave()-->构造Insert SQL-->user.id=new id-->将user对象放入内部缓存-->对级联关系进行递归处理。

Session.update:根据待更新实体对象的Key在当前session的内部缓存中进行查找(一个Persistent实体对象调用update并不会产生作用)-->初始化实体对象的状态信息(作为之后脏数据检查的依据),并将其纳入内部缓存。

Session.saveOrUpdate:实际上是save和update方法的组合应用,它本身并没有增加新的功能特性,但是却为我们的应用层开发提供了一个相当便捷的功能选择。--无需关心传入的user参数到底是怎样的状态。
public interface IUserDAO{
public TUser getUser(String id);
public void saveUser(TUser user);
}

6),数据批量操作

(1),数据批量导入
<session-factory>
...
<property name="hibernate.jdbc.batch_size">25</property>
...
</session.factory>

public void importUserList() throws HibernateException{
Transaction tx = session.beginTransaction();
for(int i=0;i<10000;i++){
TUser user = new TUser();
user.setName("user" + i);
session.save(user);

if(i%25==0){ //以每25个数据作为一个处理单元
session.flush();
session.clear();
}
}
tx.commit();
}

(2),数据批量删除

内存消耗:
Transaction tx = session.beginTransaction();
String hql = "from TUser";
Query query = session.createQuery(hql);
ScrollableResults scRes = query.scroll();
while(scRes.next()){
TUser user = (TUser)scRes.get(0);
session.delete(user);
}
tx.commit();

迭代删除操作的执行效率:采用调整hibernate.jdbc.batch_size参数来解决。

BULK delete/update:
Transaction tx = session.beginTransaction();
String hql = "delete TUser";
Query query = session.createQuery(hql);
int ret = query.executeUpdate();
tx.commit();
--------批量删除与缓存管理的矛盾仍然存在。---关闭二级缓存,调用不同session解决内部缓存带来的问题。

7),Collection

(1),Collection类型(org.hibernate.collection)
无序集:Set,Bag,Map
有序集:List
---无序与有序,是针对Hibernate数据持久过程中,是否保持数据集合中的记录排列输序加以区分的。

Set:
陷阱--->
<set name="addresses" table="t_address" lazy="false">
<key column="user_id"/>
<one-to-many class="TAddress"/>
</set>
<set name="addresses" table="t_address" lazy="false">
<key column="user_id"/>
<element type="string" column="address"/>
</set>

Bag:允许包含重复元素的“Set”。---基于List但屏蔽其有序性。
idbag:
<idbag name="addresses" lazy="true" table="t_address">
<collection-id type="int" column="id">
<generator class="identity"/>
</collention-id>
<key column="user_id">
<element type="string" column="address"/>
</idbag>

Map:键值对应关系。
<map name="addresses" lazy="true" table="t_address">
<key column="user_id"/>
<index type="string" column="type"/>
<element type="string" column="address"/>
</map>
index:要求在数据集中取值唯一。
TUser user = (TUser)session.load(TUser.class,new Integer(1));
user.getAddresses().get("Home");//读取家庭地址
user.getAddresses().get("Office");//读取办公地址

List:实现了集合内元素顺序的持久化。
<list name="addresses" lazy="true" table="t_address">
<key column="user_id"/>
<index type="integer" column="idx"/>
<element type="string" column="address"/>
</list>

8),结果集排序
排序强调的是针对现有数据,以特定的逻辑对其排列此序进行调整,而排序的结果,是数据在内存中的某种排列次序,属于临时状态。

排序方式:
Sort--->Collection中的数据排序,如对一个List中的元素先后进行排序调整。(JVM)
<set ... sort="natural".../>
如果期望指定某种特殊的排序算法,那么可以实现java.util.Comparator接口,如:
package org.sample
public class LengthComparator implements Comparator{
public int compare(Object obj1,Object obj2){
String str1 = String.valueOf(Obj1);
String str2 = String.valueOf(Obj2);
return str1.length()-str2.length();
}
}
<set ... sort="org.sample.LengthComparator".../>
---Bag,List不支持sort排序方式。

order-by--->对数据库执行Select SQL时,由order by子句实现的数据排序方式。(数据库)
<set ... order-by="address desc".../>
List不支持order-by排序。
分享到:
评论

相关推荐

    hibernate 持久层优化

    使用hibernate 进行持久层操作时,查询响应时间比较与最佳选择

    基于Hibernate的持久层增强工具包设计源码

    Hibernate增强工具包专注于对Hibernate持久层的增强,提供更加精简的CRUD(创建、读取、更新、删除)操作,同时保持对Hibernate核心功能的兼容。项目结构清晰,代码注释详尽,适合用于学习和研究Hibernate在Java应用...

    Hibernate数据持久层框架.rar

    是一款持久层框架,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。JPA的对象关系映射(ORM)模型是基于Hibernate。是一款面向对象的ORM框架,JPA不...

    Hibernate 增强工具包 - 只做增强不做改变,更加精简持久层CRUD操作

    Hibernate 增强工具包 - 只做增强不做改变,更加精简持久层CRUD操作;纯正血统(完全继承原生 Hibernate 的所有特性);最少依赖(仅仅依赖 Hibernate);自动生成代码(简化操作,使其专注于业务);自定义操作...

    Hibernate的高级操作.pdf

    基于Hibernate持久层开发,Hibernate的回调和拦截机制

    Java持久层框架之争

    持久层框架可以帮助我们管理数据访问、数据库连接、事务处理等复杂的数据库操作,从而提升开发效率和代码质量。  然而,在众多的Java持久层框架中,选择最佳方案并不是一件容易的事情。每个框架都有各自的特点和...

    hibernate-prj1

    2、Hibernate 的主要作用是简化应用的数据持久层编程,不仅能管理 Java 类到数 据库表的映射,还提供数据查询和获取数据的方法,从而大幅减少了开发人 员编写 SQL 和 JDBC 代码的时间; 3、Hibernate 框架主要包括...

    DSDAO数据库持久层

    DSDAO数据库持久层是自主研发的一套基于JDBC的数据库持久层框架,即支持对象式的操作也支持SQL操作,整个持久层的使用除了需要配置数据库连接外,无需其它配置,使用上比HIBERNATE/MYBIATIS更简单,而功能与这些知名...

    持久层框架ibatis学习笔记

    iBatis 是一套简单易学的持久层框架,应用范围也比较广发,与jdbc 相比,简化了JDBC 的百分之61 的代码量,将Sql 语言与java 程序分离,便于维护和开发,ORM 关系映射上比 JDBC 更加容易更加方便这些有点足以让我们...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     8.3 Java对象在Hibernate持久化层的状态  8.3.1 临时对象的特征  8.3.2 持久化对象的特征  8.3.3 被删除对象的特征  8.3.4 游离对象的特征  8.4 Session接口的详细用法  8.4.1 Session的save()和persist()...

    基于JAVA struts+hibernate实现的网络购物系统的毕业设计,该系统采用MVC三层架构,分离了表现层、业务逻辑层和

    这些Action类通过Hibernate框架操作数据持久层中的数据表,完成商品信息查询、添加、修改、删除等操作,以及订单和支付记录的添加操作。 数据持久层使用Hibernate框架实现,定义了商品、用户、订单、订单详情等实体类,...

    第24次课-1 Spring与Hibernate的整合

    可以完成大量Hibernate持久层的操作。 24.3 Spring对Hibernate的简化 24.3.3 HibernateTemplate概述 Spring提供了org.springframework.orm.hibernate3.HibernateTemplate类和org.springframework.orm.hibernate3....

    MyEclipse中hibernate的配置

    Hibernate是现在企业运用的最主流持久层中间件技术,恩,貌似可以这么说吧。 和JDBC比较一下,同样都是数据库中间件(DM,Database Middleware),JDBC利用SQL语言操作的是数据,而Hibernate则是利用自己的查询语言...

    彻底解决hibernate常见难点.zip

    N关系时保存技巧、Hibernate缓存机制、Hibernate批量处理数据、Hibernate三种继承映射策略、hibernate映射体系、Hibernate主键生成策略、持久层DAO设计建议、基于xml文件的bean、使用HibernateAPI在Spring中、事务...

    利用Spring来管理Hibernate完整例子

    其中Hibernate每次都需要手动创建SessionFactory,Session,手动开启提交关闭事务。而这一切操作完全是由Spring来代替。使持久层更加方便,使开发人员减少持久层操作,把注意力放到业务上。

    Hibernate框架包

    既然知道了什么是持久化,那么持久化层也就应该有点思路了,这里吧数据库看成是内存的一部分,我们就当做将数据保存到数据库中,就保存到了硬盘中一样,所以在操作数据库的或者跟数据库打交道的那一层就是就持久层,...

    Struts2+Hibernate3+Spring2.5整合详细步骤+实例可运行代码

    1. word文档记录了Struts2+Hibernate3+Spring2.5整合详细步骤,附有操作步骤的图示参考,并给出了各个步骤的注意事项; 2. 源代码实例包括一个完整模块的增删改查操作,可直接运行,可以在此基础上直接进行自己系统...

    自己写的一个持久化层

    自己写的一个持久化层,模仿Hibernate的操作

Global site tag (gtag.js) - Google Analytics