`
fangang
  • 浏览: 876292 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
311c4c32-b171-3767-b974-d26acf661fb2
谈谈用例模型的那些事儿
浏览量:38604
767c50c5-189c-3525-a93f-5884d146ee78
一次迭代式开发的研究
浏览量:68779
03a3e133-6080-3bc8-a960-9d915ed9eabc
我们应当怎样做需求分析
浏览量:409788
753f3c56-c831-3add-ba41-b3b70d6d913f
重构,是这样干的
浏览量:91315
社区版块
存档分类
最新评论

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

阅读更多

最近我和一朋友讨论如何在在spring+hibernate框架下设计通用的查询程序。设计通用的查询程序,对于单表查询比较容易,只要把要查询的值对象和查询条件作为条件传递给后台就可以执行查询了。而从结果集中取值也比较容易,因为结果集就是这个值对象的集合。但要是设计一个通用的多表查询程序就比较复杂了,涉及多个值对象、值对象的关联、查询条件的前缀、取值等等问题。我提出一个观点,现在的hibernate可以不需要多表查询,运用单表查询以及值对象的各种关系就可以完全实现所有多表查询的功能。

为什么这么说呢?比如我们需要获得一个部门及其下面的所有员工。过去我们需要将部门和员工这2个表进行关联进行多表查询,但现在我们只需要在设计部门值对象的时候为其增加一个一对多关联,然后通过单表查询部门表,在每个部门值对象的员工属性中就有其所有的员工了。再比如,如果我们需要在查询员工的时候显示各个员工所在部门的部门名称,现在我们也同样不需要多表查询了。只需要在员工值对象中建立员工到部门的多对一关系,在单表查询员工的时候,每个员工值对象中都有部门属性,对应的是部门值对象,包含了其所在部门的全部信息。

以上提供了运用单表查询以及值对象的各种关系替代多表查询最常见的2种情况,而hibernate还提供了一对一、多对多、3种继承关系,我认为可以含盖几乎所有需要使用多表查询的应用。所以我认为,hibernate发展到现在,我们可以几乎不需要使用多表查询。编写一个通用的单表查询程序就可以应付大多数使用hibernate的查询程序,除了复杂查询。hibernate不适用于复杂查询,不论是易用性、效率来看都不适合。

分享到:
评论
49 楼 yanxing2012 2014-05-01  
fangang 写道
coolnight 写道
需要分页的时候, 这一对多关联如何做??

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

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

关于分页的实现我的示例http://fangang.iteye.com/blog/120768中的com.htxx.service.dao.BasicDao可以给你一点儿参考。

看到这个问题和回答,如梦初醒。
48 楼 yanxing2012 2014-05-01  
beyondqinghua 写道
是的,使用spring结合hibernate来操作是不会出现问题,
但是LZ有没有碰到过这种问题,以前我做的一些东西没有使用spring来管理hibernate进行数据库操作,而是使用hibernate直接查询数据库,多表查询的时候如果只是加载单个表,比如部门和员工是一对多的,如果我把部门的信息放在List里面,查询结束后需要session.close()吧,如果我再用list去读取员工的数据,将会出现session is closed错误,数据不能进行lazing!


hibernate默认采用延迟加载,指定lazy="false"应该可以吧
47 楼 lwqenter 2012-05-09  
fangang 写道
lwqenter 写道
我们项目用的数据库是mysql,楼主对uuid+innodb(表引擎)性能很低有什么看法和办法?

不要这样使用,效率非常差。如果生成主键时需要从数据库端生成,那么无疑将增大数据库的访问次数,那么就是降低系统运行效率。试想,在一次操作中,应用端生成主键访问一次数据库,执行持久化时访问数据库一次,就是2次;如果生成主键不访问数据库,仅持久化时访问数据库,数据库访问量将减少50%,性能将有多大的提升,特别在那些并发访问压力巨大的系统中。因此我采用的策略就是uuid,uuid虽然从理论上可能出现重复,但概率简直是千年等一回。

但uuid的缺陷是无序,如果用户要求一个有序的编号时,就需要innodb,但建议不要建在主键里,另做一个字段

-----
我们的主键用的就是hibernate的UUID,同时我们的需求要处理事务,所以用了innodb,正如你所说uuid是无序的,但innodb是进行有序挺入的,所以效率就很低,还没找到好的解决办法
46 楼 fangang 2012-05-08  
lwqenter 写道
使用的字段一定要有选择性,也就是当该字段的值确定以后查询出来的结果尽量上那么这个字段的选择性就高
---这块没看懂,使用的字段是指做索引的字段吗,后面这句是什么意思

不能使用延迟查询---什么情况下不能使用延迟查询?很多时候都是要显示关联的例表的啊,都要显示数据,这时就不能使用延迟查询,是这样吗


数据库建索引是非常有讲究的,建得不好反倒会降低查询效率。一般来说,索引字段必须有选择性,什么意思?比如说,采用主键选择性最强,因为输入一个主键值只能获得一条记录;采用一些序号、日期次之,假如一个表单表,一日生成数据数十条,当输入一个日期时产生的结果也就数十条,如果采用一些序号,可能产生数据就几条,我说的序号是指那些一个表对另一个表主键的引用。采用各种代码编号是选择性最差的,一般都不建议采用,比如一个代码有10条记录,另一个100万的表用了一个代码,那么输入一个代码产生的结果将是10万条记录。用这样的索引不如不用。记住,假如输入任意一个值得到的结果越少,那么这个字段的选择性就越高。

延迟加载在BUS层是有效的、在MVC层是有效的,但再往前端呢,到页面端就无效了,所以如果到页面端再去访问某个属性就什么也得不到了,需要预先加载。这问题在使用dwr框架的系统中特别突出。
45 楼 fangang 2012-05-08  
lwqenter 写道
我们项目用的数据库是mysql,楼主对uuid+innodb(表引擎)性能很低有什么看法和办法?

不要这样使用,效率非常差。如果生成主键时需要从数据库端生成,那么无疑将增大数据库的访问次数,那么就是降低系统运行效率。试想,在一次操作中,应用端生成主键访问一次数据库,执行持久化时访问数据库一次,就是2次;如果生成主键不访问数据库,仅持久化时访问数据库,数据库访问量将减少50%,性能将有多大的提升,特别在那些并发访问压力巨大的系统中。因此我采用的策略就是uuid,uuid虽然从理论上可能出现重复,但概率简直是千年等一回。

但uuid的缺陷是无序,如果用户要求一个有序的编号时,就需要innodb,但建议不要建在主键里,另做一个字段
44 楼 lwqenter 2012-05-06  
楼主的hiberante查询篇让人受教了
43 楼 lwqenter 2012-05-06  
uuid
fangang 写道
seacat 写道
Java对象没必要一直存在于内存中

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


-----
我们项目用的数据库是mysql,楼主对uuid+innodb(表引擎)性能很低有什么看法和办法?
42 楼 lwqenter 2012-05-06  
fangang 写道
在数据库中建索引当然是有必要(谈到索引罗嗦一下,索引在精而不在多,使用的字段一定要有选择性,也就是当该字段的值确定以后查询出来的结果尽量上那么这个字段的选择性就高),但站在hibernate的角度说,如果不能使用延迟查询,应当尽量不用一对多和多对多关系,也尽量不要采用双向关联。

另外,使用hibernate2也不是完全不能用延迟查询。如果将bus设置为要用事务处理,并且在bus层保证在bus以下各层要使用的属性,bus都已经预装载了,同样可以使用延迟查询来提高运行效率。在我的示例http://fangang.iteye.com/blog/120768中的com.htxx.service.dao.LasyPropertyProxy也许在预装载方面给你一些提示。




使用的字段一定要有选择性,也就是当该字段的值确定以后查询出来的结果尽量上那么这个字段的选择性就高
---这块没看懂,使用的字段是指做索引的字段吗,后面这句是什么意思

不能使用延迟查询---什么情况下不能使用延迟查询?很多时候都是要显示关联的例表的啊,都要显示数据,这时就不能使用延迟查询,是这样吗
41 楼 nbawukun 2008-05-07  
hibernate对于连接查询的支持不是很好,实际项目中还是有必要使用连接查询的,如果直接根据hibernate的映射关系来获得对象,有的时候效率很低,它莫名其妙的生成了很多乱七八杂的sql语句
40 楼 maming2000 2008-05-05  
作view正解,只读表很好用,当成一个只读业务对象就OK了。
39 楼 rukyo 2008-04-21  
我觉得复杂查询时候还是需要用jdbc,把sql写在配置文件中
38 楼 rukyo 2008-04-21  
搞个报表就够你受了,当然有需要多表的时候。
37 楼 Fly_m 2008-04-18  
spring的openSessionInViewFilter是个好东东.
复杂的东西还是由jdbc吧,hibernate管不了那个.
36 楼 beyondqinghua 2008-04-17  
是的,使用spring结合hibernate来操作是不会出现问题,
但是LZ有没有碰到过这种问题,以前我做的一些东西没有使用spring来管理hibernate进行数据库操作,而是使用hibernate直接查询数据库,多表查询的时候如果只是加载单个表,比如部门和员工是一对多的,如果我把部门的信息放在List里面,查询结束后需要session.close()吧,如果我再用list去读取员工的数据,将会出现session is closed错误,数据不能进行lazing!

35 楼 devil_javaMode 2008-04-17  
总的来说。看了这多收获不少。
我对于复杂查询一般都采用jdbc,有时候其实蛮享受那种拼结sql语句的感觉`呵呵。
34 楼 fangang 2007-10-18  
kyo100900 写道
你的选择也决定你的代码量,一般来说大家更喜欢偷懒吧。呵呵

我是比较喜欢偷懒的那种懒汉,哈哈。不过我始终相信代码少出错也就少。
33 楼 kyo100900 2007-10-17  
你的选择也决定你的代码量,一般来说大家更喜欢偷懒吧。呵呵
32 楼 guofei_gf 2007-10-17  
哪个适用选哪个
31 楼 kaki 2007-10-16  
也就是说把复杂的东西交给数据库处理??
30 楼 fangang 2007-10-15  
总结起来,使用hibernate完成复杂查询有性能问题似乎大家都没有异议,而解决办法有二:使用视图和JDBC。使用视图,既可以使用SQL建立视图,解决hibernate不能解决的问题,又可以对视图建值对象,使得JDBC和hibernate这对熊掌和鱼可以兼得,着实不错。如果通过spring的代理使用JDBC,其实编程也是挺简单的,少了很多需要考虑的问题(如获得连接、传值、关闭连接、内存泄漏等问题)。更重要是通过JDBC可以将SQL保存在数据库或配置文件中,增加系统灵活性和可维护性。而有些操作,如blob、clob采用JDBC似乎也更加可靠一些。

相关推荐

    hibernate多表联合查询

    在实际项目开发中,我们经常需要处理复杂的数据库查询,特别是涉及到多个表之间的关联查询。Hibernate作为一款流行的Java持久层框架,提供了一种非常便捷的方式来处理这些问题。本文将详细介绍如何利用Hibernate进行...

    Hibernate连表查询 Hibernate连表查询

    在实际开发过程中,我们经常会遇到需要从多个表中获取数据的情况,这时就需要用到连表查询。 #### 1. HBM 映射文件 在提供的内容中,出现了两个HBM映射文件:`TopProductsDeputy.hbm.xml` 和 `TopProducts.hbm.xml...

    Hibernate各种查询:联表查询 分页查询 位置参数查询(?) 占位符查询(冒号查询) 统计查询

    本篇文章将详细解析Hibernate中的几种主要查询方式,包括联表查询、分页查询、位置参数查询、占位符查询(冒号查询)以及统计查询,这些都是在实际开发中非常常见的需求。 首先,我们来看**联表查询**。在Hibernate...

    Hibernate 多表连接分页查询示范项目

    2. **定义关联**:在实体类中使用 @ManyToOne, @OneToOne, @OneToMany 或 @ManyToMany 等注解定义表之间的关联关系。 3. **创建 SessionFactory**:配置 Hibernate 的属性,如数据库连接信息,生成 SessionFactory ...

    hibernate 多表查询

    hibernate 多表查询 hibernate 多表不同于一般的sql嵌套查询,嵌套查询是不支持的,所以必须要配置好才能实现多表!只要配置好了,还是特别好用的

    hibernate 进行多表查询每个表中各取几个字段

    本篇文章将探讨如何在Hibernate中进行多表查询,并从每个表中选取特定的字段。 一、Hibernate的多表查询基础 在Hibernate中,多表查询通常涉及到关联关系的映射,包括一对一(OneToOne)、一对多(OneToMany)、多...

    hibernate代码优化基于配置的多表查询

    在Java的Web开发中,Hibernate是一个非常流行的ORM...通过以上这些策略,我们可以优化基于配置的多表查询,提升Hibernate在实际应用中的性能。在具体实践中,应结合项目需求和数据库设计灵活调整,以达到最佳效果。

    Hibernate_query查询数据表中的一个字段.

    在使用Hibernate进行查询前,首先需要进行基本的配置,包括创建hibernate.cfg.xml配置文件,设置数据库连接信息,以及实体类和表的映射文件(.hbm.xml)。 三、Entity类与表的映射 在Hibernate中,每一个数据库表都...

    day36 04-Hibernate检索方式:多表连接查询

    在多表连接查询的场景下,Hibernate提供了几种不同的方法来处理数据关联,包括HQL(Hibernate Query Language)查询、Criteria API以及传统的JPA(Java Persistence API)注解。 1. **HQL查询**: Hibernate Query...

    Hibernate(多对多表操作)

    3. **配置映射文件**:虽然在JPA中,我们通常使用注解进行映射,但在某些情况下,可能还需要编写XML映射文件。在`hibernate.cfg.xml`或`persistence.xml`中添加相应的配置。 4. **处理关联**:在业务逻辑中,我们...

    hibernate的多态查询

    标题“hibernate的多态查询”指的是在Hibernate框架中,如何进行涉及不同子类的对象查询,这是ORM(对象关系映射)中的一个重要特性,旨在提高代码的灵活性和可扩展性。多态查询允许我们编写一次查询,而无需关心...

    Hibernate多对多关联添加及查询示例

    在Java编程领域,Hibernate是一个非常重要的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者可以使用面向对象的方式来处理数据。本示例主要关注的是Hibernate中的多对多关联映射及其添加与查询方法。 多...

    Hibernate-基础联表模板

    在实际业务中,往往需要涉及多张表的数据交互,这就需要用到联表查询。Hibernate提供了多种联表查询方式,如:`JOIN`, `LEFT JOIN`, `RIGHT JOIN`, `FULL JOIN`等,这些都可以通过HQL(Hibernate Query Language)...

    Struts2+Hibernate实现一对多联表查询

    在Hibernate中,这种关系可以通过在实体类中使用`@OneToMany`注解来定义。例如,在`Department`类中,我们可以定义一个`List<Employee>`类型的属性,表示部门下的所有员工,同时通过`mappedBy`指定在`Employee`类中...

    Hibernate_query查询数据表中部分字段.

    在进行字段查询时,我们需要在映射文件中明确指出哪些字段会被使用。 1. **Hibernate查询语言(HQL)**: Hibernate 提供了自己的查询语言 HQL,类似于 SQL,但面向对象。例如,如果你想查询一个表中特定的字段,...

    hibernate中文参考文档

    11. Hibernate查询语言:Hibernate Query Language(HQL)是用于操作持久化数据的一种面向对象的查询语言,这部分将介绍HQL的基本语法和高级特性。 12. 条件查询:条件查询是数据库操作中常见的需求,文档会讲解...

    Hibernate5中文用户使用手册

    Hibernate5中文用户使用手册涉及了Hibernate框架的核心使用方法和高级特性,覆盖了从基础概念到高级特性的全方位内容,本手册的结构和内容包含以下几个方面: Hibernate概述:Hibernate是一个纯Java的关系型持久层...

    Hibernate多表查询.txt

    在多表查询中,HQL支持通过逗号分隔的表名来表示联合查询,同时利用`where`子句来定义表之间的关联条件。例如,在示例代码中,通过`from tBookInfo book, BookSelection sel where book.id = sel.bookId`这样的HQL...

    关于Hibernate3中文查询出错问题的解决

    在使用Hibernate3进行数据库操作时,中文查询出错是一个常见的问题,这主要涉及到字符编码、数据库配置以及Hibernate的设置等多个方面。以下将详细介绍如何解决这个问题。 首先,我们要明白错误的根源通常在于字符...

    hibernate实现动态SQL查询

    在Hibernate中,我们通常使用HQL(Hibernate Query Language)或Criteria API进行查询,但这些方式并不支持复杂的动态查询。为了实现动态SQL,我们可以借助于Hibernate的QBC(Query By Criteria)和Criteria API,...

Global site tag (gtag.js) - Google Analytics