
Hibernate取子表信息.pdf
5页hibernate使用 from (select ,,)子查询的方法分类: JSP/Java 2008-10-28 14:47 3116人阅读 评论(1) 收藏 举报今天徒弟用到了一句复杂的查询语句结果执行报错,但是在SQL中执行没有问题,于是来求助 我了语句的 HQL/SQL 格式如下:select count(1) ,cxltype,sum(dzsje),sum(iperson)from (select xl.cxltype,g.iperson,(select sum(y.dzsje) from Ysklist as y where y.cykpid = g.cregno) as dzsje from Guestreg as g,Xl as xl where g.xluuid = xl.uuid ) as t where ,, group by t.cxltype 结果执行出错,最终发现, HQL 无法支持 from 后面跟子查询的方式,网上查了N多资料,发现遇到这个 问题的人还真是不少,但每一个相关的问题帖都没有满意的答复,甚至于多数都是没有跟帖的一阵心寒,hibernate叱咤风云,竟然对这个支持如此之弱?虽然这个语句可以通过另外的方法来做(比 如建视图或者直接使用SQL来做),但总是不甘心,于是又开始查阅各处资料,最后找到了思路,觉 得既然 HQL 不支持,那么只能把这种子查询封装为对象来做了,那么肯定是需要 hbm配置这种临时的子 查询对象的,于是开始着手hbm配置的资料中查, hbm中配置对象的都是class 标签,开始把范围缩小, 针对 hbm的 class 标签的属性资料开始翻查, 找到了几个比较可能的属性, where、 subselect 、 mutable 、 entity-bean,貌似这些都可能跟临时对象有关。
于是反复尝试,并继续翻查资料最终在 Hibernate reference 3.2.0 ga 正式版中文参考手册 中找到了一些比较可靠的资料:5.1.3. class你可以使用 class 元素来定义一个持久化类:name (可选): 持久化类(或者接口)的Java 全限定名如果这个属性不存在, Hibernate将假 定这是一个非 POJO 的实体映射table (可选 - 默认是类的非全限定名 ): 对应的数据库表名discriminator-value (可选 - 默认和类名一样 ): 一个用于区分不同的子类的值,在多态行为时 使用它可以接受的值包括 null 和 not nullmutable ( 可选,默认值为 true): 表明该类的实例是可变的或者不可变的schema (可选): 覆盖在根 元素中指定的 schema名字catalog (可选): 覆盖在根 元素中指定的 catalog名字proxy ( 可选): 指定一个接口, 在延迟装载时作为代理使用你可以在这里使用该类自己的名字dynamic-update ( 可选, 默认为 false): 指定用于 UPDATE 的 SQL将会在运行时动态生成,并且 只更新那些改变过的字段。
dynamic-insert ( 可选, 默认为 false): 指定用于 INSERT的 SQL 将会在运行时动态生成,并且 只包含那些非空值字段select-before-update ( 可选, 默认为 false): 指定 Hibernate 除非确定对象真正被修改了(如 果该值为 true -译注),否则 不会执行 SQL UPDATE 操作在特定场合(实际上,它只在一个瞬 时对象( transient object)关联到一个新的 session 中时执行的 update() 中生效),这说明 Hibernate 会在 UPDATE 之前执行一次额外的SQL SELECT 操作,来决定是否应该执行 UPDATE polymorphism (多态) ( 可选, 默认值为 implicit (隐式) ): 界定是隐式还是显式的使用多态 查询(这只在 Hibernate 的具体表继承策略中用到-译注)where ( 可选) 指定一个附加的 SQLWHERE 条件, 在抓取这个类的对象时会一直增加这个条件persister (可选): 指定一个定制的 ClassPersister。
batch-size (可选, 默认是 1) 指定一个用于根据标识符 (identifier)抓取实例时使用的 “batch size“ (批次抓取数量)optimistic-lock(乐观锁定) ( 可选,默认是 version): 决定乐观锁定的策略16) lazy (可选): 通过设置 lazy=“false“, 所有的延迟加载( Lazy fetching)功能将被全部禁用 (disabled )17) entity-name (可选,默认为类名 ): Hibernate3允许一个类进行多次映射(前提是映射到不同 的表),并且允许使用 Maps或 XML代替 Java 层次的实体映射(也就是实现动态领域模型,不用 写持久化类-译注)更多信息请看第 4.4 节 “动态模型 (Dynamic models) ” and 第 18 章 XML 映射18) check ( 可选): 这是一个 SQL表达式, 用于为自动生成的schema添加多行( multi-row )约束 检 查19) rowid ( 可选): Hibernate可以使用数据库支持的所谓的ROWIDs ,例如: Oracle 数据库,如果 你设置这个可选的rowid , Hibernate可以使用额外的字段rowid 实现快速更新。
ROWID 是这个 功能实现的重点,它代表了一个存储元组( tuple )的物理位置20) subselect (可选): 它将一个不可变( immutable )并且只读的实体映射到一个数据库的子查询中当你想用视图代替一张基本表的时候,这是有用的,但最好不要这样做更多的介绍请看下 面内容21) abstract (可选): 用于在 的继承结构(hierarchies)中标识抽象超类注意其中红色的字体,这就是关键之处,往下我找到了相关的内容:对 Hibernate 映射来说视图和表是没有区别的,这是因为它们在数据层都是透明的(注意:一些数据 库不支持视图属性,特别是更新的时候)有时你想使用视图,但却不能在数据库中创建它(例如: 在遗留的 schema中)这样的话,你可以映射一个不可变的(immutable)并且是只读的实体到一个 给定的 SQL子查询表达式:select item.name, max(bid.amount), count(*) from item join bid on bid.item_id = item.id group by item.name ... 定义这个实体用到的表为同步(synchronize ),确保自动刷新( auto-flush)正确执行,并且依赖原 实体的查询不会返回过期数据。
在属性元素和一个嵌套映射元素中都可见显然这就是我一直在找的东东了,hibernate支持自身建立视图,而不需要依赖于数据库虽然它本 身的说法这是用来替代视图的,但其实这就是带子查询的sql ,看我们最终的配置结果临时子查询视图 Bean[其中第二个非默认的构造函数是不能少的,不然对象无法创建] :1. public class TestBean { 2. private Integer id; 3. private String cxltype; 4. private Integer iperson; 5. private Double dzsje; 6. public TestBean(){} 7. 8. public TestBean(String cxltype, Integer iperson, Double dzsje) { 9. super(); 10. this.cxltype = cxltype; 11. this.iperson = iperson; 12. this.dzsje = dzsje; 13. } 14. public String getCxltype() { 15. return cxltype; 16. } 17. public void setCxltype(String cxltype) { 18. this.cxltype = cxltype; 19. } 20. public Integer getIperson() { 21. return iperson; 22. } 23. public void setIperson(Integer iperson) { 24. this.iperson = iperson; 25. } 26. public Double getDzsje() { 27. return dzsje; 28. } 29. public void setDzsje(Double dzsje) { 30. this.dzsje = dzsje; 31. } 32. 33. public Integer getId() { 34. return id; 35. } 36. 37. public void setId(Integer id) { 38. this.id = id; 39. } 40.} TestBean 的 hbm配置:1. 2. 3. 4. select xl.cxltype,g.iperson,(select sum(y.dzsje) from Ysklist as y where y. cykpid = g.cregno) as dzsje 5. from Guestreg as g,Xl as xl 6. where g.xluuid = xl.uuid 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. HQL 语句:select t.cxltype,sum(t.dzsje),sum(t.iperson) from TestBean as t where ,, group by t.cxltypeHibernate 生成的 SQL语句:Hibernate: select testbean0_.cxltype as col_0_0_, sum(testbean0_.dzsje) as col_1_0_, sum(testbean0_.iperson) as col_2_0_ from ( select xl.cxltype,g.iperson,(select sum(y.dzsje) from Ysklist as y where y.cykpid = 。
