浏览 7138 次
锁定老帖子 主题:不总结就得付出代价
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (1)
|
|
---|---|
作者 | 正文 |
发表时间:2010-03-06
最后修改:2010-03-06
问题列表: 1,分组查询 2,left outer join/right outer join/full outer join/inner outer join区别 问题1:分组查询 分组查询不就是group by嘛,确实是这样。但是在hibernate里面查出来的数据就不一样,我所有指的定是每列数据。例如: I)HQL(Hibernate Query Language) from SysUser user group by userId 使用HQL查询出来的是符合条件,所有字段的数据 II)QBC(Query By Criteria) DetacheCriteria dc = DetachedCriteria.forClass(SysUser.class); dc.setProjection(Projections.groupProperty("this.userId")); List<SysUser> list = sysUserService.findByCriteria(dc); 这段码看上去没有一点错,我们还是用后面打印的SQL语句来说话吧。这里我就手工模拟写出后台打印SQL语句,其实意思是一样。 select this_.user_id from sys_user this_ group by this_.user_id 看完这一段SQL语句,你还认为上面代码没有错吗?相信你一眼就可以看会出现什么样的问题:ClassCastException这个异常会抛出来。问题出来那总得有解决方案吧,肯定是有的。具体怎么选择那你自己的事了。 方案一(不推荐):直接用SQL查询 方案二:是用示例查询 select new SysUser(user.userId,user.name) from SysUser user group by user.userId; 这样查底的前提是SysUser类中必须有一个SysUser(userId,name)构造方法 方案三:直接返回对象,这又是什么意思呢?看下面代码就知道意思啦 select user from SysUser user group by user.userId 查询这样的简单的表不用费多大劲。下面再看看一个复杂点的表结构。 @Entity @Table(name = "doc_document") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class DocDocument implements java.io.Serializable { private static final long serialVersionUID = 8811969619989885931L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "doc_document_id") private Integer docDocumentId; @OneToMany(mappedBy = "docDocument") private Set<DocReceiveApprove> docReceiveApproves = new HashSet<DocReceiveApprove>( 0); @OneToMany(mappedBy = "docDocument") private Set<DocFbTotal> docFbTotals = new HashSet<DocFbTotal>(0); @OneToMany(mappedBy = "docDocument") private Set<DocSend> docSends = new HashSet<DocSend>(0); @OneToMany(mappedBy = "docDocument") private Set<DocAttach> docAttachs = new HashSet<DocAttach>(0); @OneToMany(mappedBy="docDocument") private Set<DocDocumentReturn> docDocumentReturns = new HashSet<DocDocumentReturn>(0); //@Fetch(FetchMode.SELECT) @OneToMany(mappedBy="docDocument") private Set<DocDocumentUser> dcDocumentUsers = new HashSet<DocDocumentUser>(0); ........ } @Entity @Table(name = "doc_document_user") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class DocDocumentUser implements java.io.Serializable { private static final long serialVersionUID = 8811969619989885931L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "doc_document_user_id") private Integer docDocumentUserId; private Integer isflow; @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE}) @JoinColumn(name = "doc_document_id") private DocDocument docDocument; @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }) @JoinColumn(name = "user_id") private CommonUser commonUser; ......... } @Entity @Table(name="common_user") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class CommonUser implements java.io.Serializable { private static final long serialVersionUID = 6147253484121456257L; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @JoinColumn(name = "user_id") private Integer userId;//用户ID //@Fetch(FetchMode.SELECT) @OneToMany(mappedBy="commonUser") private Set<DocDocumentUser> dcDocumentUsers = new HashSet<DocDocumentUser>(0); @OneToMany(mappedBy="commonUser") private Set<DocFbTotal> docFbTotals = new HashSet<DocFbTotal>(0); @OneToMany(mappedBy="commonUser") private Set<DocReceiveApproveCheck> docReceiveApproveChecks = new HashSet<DocReceiveApproveCheck>(0); @OneToMany(mappedBy="commonUser") private Set<DocReceiveinfoHst> docReceiveinfoHsts = new HashSet<DocReceiveinfoHst>(0); @OneToMany(mappedBy="commonUser") private Set<DocRrSend> docRrSends = new HashSet<DocRrSend>(0); @OneToMany(mappedBy="commonUser") private Set<DocReceiveApproveDraw> docReceiveApproveDraws = new HashSet<DocReceiveApproveDraw>(0); @OneToMany(mappedBy="commonUser") private Set<InfoSender> infoSenders = new HashSet<InfoSender>(0); @OneToMany(mappedBy="commonUser") private Set<DocPrintTrackHst> docPrintTrackHsts = new HashSet<DocPrintTrackHst>(0); @OneToMany(mappedBy="commonUser") private Set<LogOperation> logOperations = new HashSet<LogOperation>(0); ...... } 代码就贴一部分,可以达到理解的用途就行。 下面方法的目录还是按组查询: public List<DocDocument> getWaitDocument() { DetachedCriteria dc = DetachedCriteria.forClass(DocDocument.class); dc.createCriteria("dcDocumentUsers", "ddu"); dc.setFetchMode("ddu", FetchMode.SELECT); dc.add(Restrictions.eq("ddu.dealstatus", "1")); dc.createCriteria("ddu.commonUser", "user"); dc.add(Restrictions.eq("user.userCode", "111")); dc.setProjection(Projections.groupProperty("this.docDocumentId")); List<DocDocument> list = this.documentService.findByCriteria(dc); } 好啦,问题源肯定不用说就可以看出来啦。 如果我想得到DocDocument对象的某个Set集合对象,我想方案一/方案二全部用不上了。但是方案三就得改造一下,如下: String hql = "select doc from DocDocument as doc left join doc.dcDocumentUsers as ddu left join ddu.commonUser as user group by doc.docDocumentId order by doc.docDocumentId desc"; 好啦问题总算解决啦。 总结一下,我们的解决方案用的就是下一个问题所要提到的东西。那咱们就进入第二个问题讲解。 首先我们得了解一下,left outer join/right outer join/full outer join/inner outer join的工作原理。 引用 假设a表和b表的数据是这样的。 a b id name id stock 1 a 1 15 2 b 2 50 3 c select * from a inner join b on a.id=b.id 这个语法是连接查询中的内连接,它产生的结果是 两个表相匹配的记录出现在结果列表中。 根据上面的表,出现的结果是这样的 a.id name b.id stock 1 a 1 15 2 b 2 50 ---------------------------- select * from a,b where a.id=b.id 这个语法是内连接的另外一种写法,其执行结果与inner join 一样 -------------------------------- select * from a left/right join b on a.id=b.id 这个是外连接语法中的左外连接或右外连接 如果是左外连接的话,它将显示a表的所有记录, select a.*,b.* from a left join b on a.id=b.id 查询的结果是这样的: a.id name b.id stock 1 a 1 15 2 b 2 50 3 c null null -------------------------------------------- 如果是右外连接的话,它将显示b表的所有记录, select a.*,b.* from a right join b on a.id=b.id 查询的结果是这样的: a.id name b.id stock 1 a 1 15 2 b 2 50 知道原理了就知道为什么在每一个问题上面要修改一下方案三(因为查询语句返回的是三个对象的数据,也就是说三张表的数据,所以通过select doc可以得到结果)。 讲到这里截取两张Hibernate注解API文档的图片来讲解一下抓取策略。 今天就总结这两个问题 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-03-08
最后修改:2010-03-08
说实话我没看懂,或许我太笨,
QBC DetacheCriteria dc = DetachedCriteria.forClass(SysUser.class); dc.setProjection(Projections.groupProperty("this.userId")); List<SysUser> list = sysUserService.findByCriteria(dc); 出错问题的根本在于,数据库中不会允许类似下面的SQL select * from t_city group by province_id 那么我要问下 from SysUser user group by userId 这句HQL到底想得到什么? |
|
返回顶楼 | |
发表时间:2010-03-08
最后修改:2010-03-08
指定了分组字段 但是没有指定要汇总的字段?
|
|
返回顶楼 | |
发表时间:2010-03-08
下面这句确实意图不明确,没有汇总语句,在HIBERNATE中也是无法执行的,楼主有没有弄错?
xuzhfa123 写道 from SysUser user group by userId |
|
返回顶楼 | |
发表时间:2010-03-13
最后修改:2010-03-13
mlw2000 写道 说实话我没看懂,或许我太笨,
QBC DetacheCriteria dc = DetachedCriteria.forClass(SysUser.class); dc.setProjection(Projections.groupProperty("this.userId")); List<SysUser> list = sysUserService.findByCriteria(dc); 出错问题的根本在于,数据库中不会允许类似下面的SQL select * from t_city group by province_id 那么我要问下 from SysUser user group by userId 这句HQL到底想得到什么? from SysUser user group by user.userId 不好意思,漏了个别名,这个跟上面提出的问题还没有太大的关联。 |
|
返回顶楼 | |