`
endeavor416
  • 浏览: 64357 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Hibernate杂项

阅读更多

文章引用于:http://blog.csdn.net/javakevin/archive/2007/12/28/1999035.aspx

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排序。

分享到:
评论

相关推荐

    Hibernate3性能优化 Hibernate_regerence3.12

    有很多人认为Hibernate天生效率比较低,确实,在普遍情况下,需要将执行转换为SQL语句的 Hibernate 的效率低于直接JDBC存取,然而,在经过比较好的性能优化之后,Hibernate的性能还是让人相当满意的, ...4.杂项

    理财管理软件CS版(JAVA+Hibernate+MySql)

    (6)选择“杂项记账”,在弹出的窗体中进行对杂项消费进行添加操作。 (7)选择“查看日消费”,在弹出的窗体中进行查看消费信息,并可以根据消费日期进行查询。 (8)选择“查看月消费”,在弹出的窗体中进行年月...

    Projects:杂项应用,项目

    3. **Java框架**:如Spring Boot、Struts或Hibernate,这些可以帮助简化开发过程,提供依赖注入、数据库连接、事务管理等功能。 4. **Android开发**:如果存在Android应用项目,会涉及Android Studio的使用,以及...

    JBoss Seam 工作原理、seam和hibernate的范例、RESTFul的seam、seam-gen起步、seam组件、配置组件、jsf,jboss、标签、PDF、注解等等

    Seam - 语境相关的组件[满江红20071230]............................................................................................................................ 1 Java EE 框架...........................

    nightowl8824_repo:杂项集合

    【标题】"nightowl8824_repo: 杂项集合" 暗示这是一个包含多种IT资源的存储库,由用户nightowl8824维护。这个仓库可能包括了他在编程、开发过程中积累的各种代码片段、工具或教程,特别关注Java语言。 【描述】...

    Android-dianping-ba-framework基于Java的web项目框架

    首先,Java作为后端编程语言,具有丰富的库和框架资源,如Spring Boot、Hibernate等,这些都可以在`dianping-ba-framework`中找到应用。Spring Boot简化了Spring应用程序的初始设置和配置,而Hibernate则提供了对象...

    EF-Core-Research-Paper:研究对象关系映射器(特别是实体框架核心)以及实现其某些功能的代码的研究论文

    ORM的调查:Hibernate,用Java编写。 b。 SQL Alchemy,用Python编写。 ODB,用C ++编写。 PHP和JavaScript等效项。杂项(Rust,Go等)。 C锐利实体框架核心。关于实体框架核心。 EF Core的组件。将类和其他语言...

    Spring.3.x企业应用开发实战(完整版).part2

    15.7 杂项 15.7.1 静态资源处理 15.7.2 装配拦截器 15.7.3 异常处理 15.8 小结 第5篇 测试及实战 第16章 实战型单元测试 16.1 单元测试概述 16.1.1 为什么需要单元测试 16.1.2 单元测试之误解 16.1.3 单元测试之...

    Spring3.x企业应用开发实战(完整版) part1

    15.7 杂项 15.7.1 静态资源处理 15.7.2 装配拦截器 15.7.3 异常处理 15.8 小结 第5篇 测试及实战 第16章 实战型单元测试 16.1 单元测试概述 16.1.1 为什么需要单元测试 16.1.2 单元测试之误解 16.1.3 单元测试之...

    JAVA开源网上会议系统

    在JAVA环境下,开发人员需要熟悉Spring、Hibernate等常用框架,以及Web开发和数据库操作的相关知识。同时,LGPL协议要求在使用和分发时尊重开源社区的贡献,确保开源精神的延续。对于有志于开发或改进此系统的人员来...

    自整理Java关于基础和框架的面试题

    - **java.util**: 提供集合框架、日期/时间设施、事件模型、杂项实用程序类(如哈希映射)、工厂、以及并发机制。 - **java.io**: 包含输入/输出类。 - **java.sql**: 用于连接和操作数据库。 ##### Get和Post的...

    55个Spring(7模块)面试题

    Spring还能与其他框架如Struts、Hibernate和EJB集成,因此被称为“框架的框架”。 1.3. Spring的优点包括: - 分层架构提供了灵活性。 - 支持POJO编程,便于持续集成和测试。 - 依赖注入和控制反转简化了JDBC...

    10-Spring面试题(131题).pdf

    - Spring提供了一个完整的框架,支持将组件如Struts、Hibernate集成到Java EE应用中。 3. **SpringFramework的优点**: - 分层架构允许用户自选组件。 - 支持POJO编程,便于集成和测试。 - 控制反转(IOC)和...

    Spring 30道面试题和答案.docx

    Spring 可以无缝集成其他流行框架,如Struts、Hibernate、EJB等,因此被誉为“框架的框架”。 Spring Framework 的优点包括: 1. 分层架构:用户可以选择需要的组件,提高灵活性。 2. POJO编程:支持简单旧式Java...

    easyjweb-src-0.8.zip_EasyJWeb_Java 8_java 邮件 系统 源码_邮件 java_邮件系统

    EasyJWeb可能使用了ORM(Object-Relational Mapping)框架如Hibernate或MyBatis,或者直接使用JDBC进行数据库操作。 4. 安全性:邮件系统涉及到用户隐私,所以安全措施是必不可少的,如加密传输、防止SQL注入、验证...

    无垠式代码生成器最新功能与文档增强版0.7.22

    1)支持三个技术栈simple(jsp,clocksimplejee或默认,s2sh(Struts2,Spring 4, Hibernate 4)和s2shcs2sh(Struts2,Spring 4, Hibernate 4 Criteria) 2)推荐工业级的S2SHC技术栈 ===============0.7.22================...

    school-notes-spring-2020:2020年Spring的学校笔记

    描述中的“科尔宾学校(及其他杂项)注意事项”可能是指这些笔记来自一个特定的教育机构——科尔宾学校,并且涵盖了多种主题,不局限于Spring框架本身。"目前在2020年Spring学期"表明这些笔记是根据当时最新的教学...

    spring data jpa1.7 中文

    @QueryHints({@QueryHint(name = "org.hibernate.cacheable", value = "true")}) List&lt;Person&gt; findAllCached(); ``` - **配置获取 LoadGraphs**: - 可以配置 LoadGraphs 来优化实体的加载过程。 - 示例: ``...

Global site tag (gtag.js) - Google Analytics