论坛首页 Java版 Hibernate

现在我们在hibernate中还需要使用多表查询吗?

浏览 9265 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
最后更新时间:2007-10-10
fangang 写道
kyo100900 写道
misschun 写道
延迟加载 不是在 配置文件里 写的吗?  不就写死了吗? 我hibernate不是很好 ,不好意思.


如果用JDBC,句句都是死的。延迟加载是一种策略,不是硬编码。Hibernate我感觉优点很多,但数据量特别大,而且关系非常复杂的时候,有点力不从心了。不知道LZ有没有好的解决办法,分享一下?


JDBC有非常多的不好,代码死、不便于维护、与数据库类型耦合等等,但它有它的优势使我们至今都不能抛弃它。它执行效率高,而且最贴近数据库,使得它可以100%完成数据查询的各种变态需求,特别是复杂查询的需求。而hibernate我们可以说出它满篇的好处,但它的致命伤是不能满足所有查询的需求。举一个我做过项目的例子。我做过一个项目,是一个分析决策系统。它的最核心部分,也是它其存在价值的部分,就是对另一个联机事务系统中的上千个日常数据的分析处理。由于业务逻辑复杂,这部分的查询语句非常复杂,常常一个语句有上百行,包含数层子查询和多个union,其间的各种函数就不用说有多少了。如果这样的语句用hibernate来完成,几乎是不可能实现,即使实现了也是效率极低的。采用jdbc应当是正确的选择。hibernate能解决70%的查询需求,但不是全部。

你说的hibernate的效率问题我也遇到过。在hibernate2的时候由于延迟查询不成熟,几乎不敢做任何一对多的关联。比如在一个内部评审项目中,一个评审计划对应多个评审者,一个评审者对应多个评审表,一个评审表对应多个疑点问题。一旦程序要装载一个评审计划,它包含的所有评审者、评审表、疑点问题,出一堆东西,简直是数据库的灾难。但是hibernate3出来以后,通过延迟查询解决了这个问题。虽然使用延迟查询似乎感觉sql语句多了不少,但评判查询效率的标准决不是语句的多少,而是语句产生结果集的多少以及执行查询其过程的效率。

但是,hibernate依然存在着执行效率的问题,这不可否认。使用hibernate始终没有单独使用jdbc的效率高,但hibernate还是有它解决执行效率的办法,那就是缓存。缓存对于hibernate解决效率问题其实作用很大。比如员工显示列表中需要显示每个员工的部门名称,也就需要为每个员工装载他所在的部门。也就是说,查出多少个员工就要执行多少次对部门的查询(部门表是一个一个查询的),但其实很多次查询都是查出的同一条部门数据。如果采用缓存,当某个部门被查出来以后就暂存在应用服务器内存中,如果需要再次装载这个部门就不需要查询数据库了,直接从应用服务器中取,对效率的提高是相当大。在使用hibernate查询时这种情况相当普遍,因此将那些基础数据表和代码表纳入缓冲是相当有用,因为它们总是1+N查询中的N。但是那些业务表,一方面是更新频繁,另一方面它们总扮演1+N查询中的1,不对它缓存也罢。不知我说的这些是否对你有帮助。



我接手的项目是Hibernate2.1的,使用起来非常慢。现在刚换成了JDBC,速度快是快了,但还是不太满意,LZ,这个时候建数据库索引和建立Lucence这样的索引,会有很大的性能区别吗?
   
0 请登录后投票
最后更新时间:2007-10-10
在数据库中建索引当然是有必要(谈到索引罗嗦一下,索引在精而不在多,使用的字段一定要有选择性,也就是当该字段的值确定以后查询出来的结果尽量上那么这个字段的选择性就高),但站在hibernate的角度说,如果不能使用延迟查询,应当尽量不用一对多和多对多关系,也尽量不要采用双向关联。

另外,使用hibernate2也不是完全不能用延迟查询。如果将bus设置为要用事务处理,并且在bus层保证在bus以下各层要使用的属性,bus都已经预装载了,同样可以使用延迟查询来提高运行效率。在我的示例http://fangang.javaeye.com/blog/120768中的com.htxx.service.dao.LasyPropertyProxy也许在预装载方面给你一些提示。
   
0 请登录后投票
最后更新时间:2007-10-10
seacat 写道
Java对象没必要一直存在于内存中

你的意思是hibernate没有必要做缓存吗?如果是这样我倒是有一些不同的看法。现在我们是3层结构,就意味着应用服务器与数据库服务器是2个不同的机器。当客户发出请求时,如果仅仅在应用服务器上进行运算以后向客户反馈,当然比从应用服务器到数据库服务器,再返回结果集到应用服务器,再反馈客户的效率高。因此,我们在编写java代码的时候,应当考虑尽量少的访问数据库。hibernate通过uuid获得主键就是一个很好的例子。从这个角度理解,hibernate采用应用服务器端的数据缓存对于提高效率就显得比较重要了,它可以大大降低应用服务器对数据库的访问。
   
0 请登录后投票
最后更新时间:2007-10-10
hibernate是人家包好的jdbc 在方便的拿来用很好

当然人家包的东西是面向大众化操做,也就是批量生产的产品
如果你有特殊的需要那就得订做--也就是说自己把jdbc包一下
   
0 请登录后投票
最后更新时间:2007-10-11
fangang 写道
seacat 写道
Java对象没必要一直存在于内存中

你的意思是hibernate没有必要做缓存吗?如果是这样我倒是有一些不同的看法。现在我们是3层结构,就意味着应用服务器与数据库服务器是2个不同的机器。当客户发出请求时,如果仅仅在应用服务器上进行运算以后向客户反馈,当然比从应用服务器到数据库服务器,再返回结果集到应用服务器,再反馈客户的效率高。因此,我们在编写java代码的时候,应当考虑尽量少的访问数据库。hibernate通过uuid获得主键就是一个很好的例子。从这个角度理解,hibernate采用应用服务器端的数据缓存对于提高效率就显得比较重要了,它可以大大降低应用服务器对数据库的访问。


是否使用缓存,与是否将数据变成固定结构的java对象,并没有必然关系。纯数据也可以缓存。而且,能够发挥明显作用的缓存,多半是读频繁而更改少的,或者读写频繁但不需要随时更新到数据库的。这与出于数据计算、更改目的而设计的对象结构,往往是不一致的。现在Hibernate一方面提供了一些方便,另一方面也很容易给人误导,开发人员建好一种对象结构就包打天下了,单纯的查询、存储用它,缓存用它,计算、处理也用它。
   
0 请登录后投票
最后更新时间:2007-10-11
在这些问题上我们都有各自不同的理解。hibernate有它的优势,但也存在问题。说它好不能包打天下,说它不好也不是一无是处,关键是我们如何取长补短,解决自己的问题。
   
0 请登录后投票
最后更新时间:2007-10-11
需要分页的时候, 这一对多关联如何做??
   
0 请登录后投票
最后更新时间:2007-10-11
你是相当于将数据库集成到hibernate中了,将原来在数据库中的查询搬到了hibernate中进行,如果hibernate有数据库的效率就可以。
   
0 请登录后投票
最后更新时间:2007-10-12
coolnight 写道
需要分页的时候, 这一对多关联如何做??

使用一对多实现分页非常麻烦,如果你需要使用一对多又要实现分页的使用,换个思路,改成多对一就可以所有这些功能。比如:

我需要显示某个部门的信息,同时又要显示该部门下的所有员工。如果采用一对多可以一次查询就实现了,即load该部门,该部门值对象的employees属性就是所有员工的信息。但是如果显示的员工需要分页就不能这样做了。那么就反过来采用多对一,查询employee,条件是employee.department=:department。这样的查询可以轻松实现分页,并且每个employee都有完整的department的信息可以用。

关于分页的实现我的示例http://fangang.javaeye.com/blog/120768中的com.htxx.service.dao.BasicDao可以给你一点儿参考。
   
0 请登录后投票
最后更新时间:2007-10-15
Hibernate确实是个好东东,但对于复杂查询存在性能上的缺陷;而用jdbc能解决性能问题,但写起来也太过繁琐.我相信很多用过了Hibernate的朋友在大多数情况下都不愿意回到用jdbc的年代.我前一个项目里有一个统计子系统,当牵涉到3张以上的表时,Hibernate就是一头老牛,怎么拉都不走,还常报内存溢出.但有不想在代码里写sql,想到的方法采用视图来进行数据汇总,然后用Hibernate对视图进行操作,速度提搞了,有免了去写sql.但在处理只取某个持久化对象的少量属性时,为了节约内存资源,写类似sql的hql很有必要!
   
0 请登录后投票
论坛首页 Java版 Hibernate

跳转论坛:
JavaEye推荐