`

hibernate 中使用union

阅读更多

    hibernate中hql是不支持union的,所以只能借助native sql了:

原来代码
     String countHql2 = "select count(distinct p) from Project as p,Comment as c,Bookmark as b where ("
+ "c.owner.id=? and p.id=c.targetId and c.targetType=500) or (b.user.id=? and p.id=b.project.id)";
     String hql2 = "select distinct p from Project as p,Comment as c,Bookmark as b where ( "+ "c.owner.id=? and p.id=c.targetId and c.targetType=500) or (b.user.id=? and p.id=b.project.id)";

    主要是找出某个人所有评论过或收藏过的项目。简单表结构如下:

    project:id   owner_id(用户id)保存项目的基本信息

    bookmark:uid(用户id),project_id(收藏的项目的id),owner_id(收藏者的id)

    comment:target_type(保存对某种对象的评论,值为500时表示的对项目的评论),target_id(保存对某种对象的评论,值为该对象的id),project_id(项目的id),owner_id(评论者的id)

    由于这个sql执行时所建的索引无法使用,而且还造成了三个表连接会有大量的无效的查询以及重复结果,最后还得要distinct可以想象执行的效率。

    只好改用union来重写,需要用到hibernate的native sql,经过努力终于找到可以用union找出整个对象以及在配置文件中与该对象有关系的对象的方法。

    代码如下:

union
String sql1 = "SELECT COUNT(*) FROM(SELECT p.id FROM project p,comment c WHERE p.id=c.target_id AND c.target_type=500 AND c.uid=" + userId
+ " UNION SELECT pr.id FROM project pr,project b WHERE pr.id=b.project_id AND b.uid=" + userId + ") AS temp";
String sql2 = "(SELECT {p.*} FROM project p,comment c WHERE p.id=c.target_id AND c.target_type=500 AND c.uid=" + userId + ")"
+ "UNION"
+ "(SELECT {p.*} FROM project p,bookmark b WHERE p.id=b.project_id AND b.uid=" + userId + ")LIMIT " + (pageIndex - 1) * maxPerPage + "," + maxPerPage;
SQLQuery query = this.getSession().createSQLQuery(sql1);
Integercount=Integer.valueOf(((BigInteger)query.uniqueResult()).toString());
SQLQuery query2 = this.getSession().createSQLQuery(sql2);
query2.addEntity("p", Project.class);
List<Project> list = query2.list();

    sql1符合条件的项目的总数。sql2求出符合条件项目的某一页。

    要注意的是:sql2中{p.*}要写成一样的。

       简而言之:select {a.*} from A a where ... union select {a.*} from A a where...

    如果还要排序的话sql2换成sql3:

需要order by时
String sql3 = "(SELECT {p.*},p.created FROM project p,comment c WHERE p.id=c.target_id AND c.target_type=500 AND c.uid=" + userId + ")"
+ "UNION"
+ "(SELECT {p.*} ,p.created FROM project p,bookmark b WHERE p.id=b.project_id AND b.uid=" + userId + ") ORDER BY created LIMIT " + (pageIndex - 1) * maxPerPage + "," + maxPerPage;

    要注意的是p.created(需要排序的那个字段) 要个别标出,因为hibernate在转换为sql是会写成 select created as ...所以排序时将不起作用,需要我们自己标出。

     ok

    

分享到:
评论

相关推荐

    Hibernate ORM - 继承关联关系之union-subclass

    本文将深入探讨Hibernate ORM中的一个特定概念——继承关联关系的“union-subclass”策略。这个策略涉及到如何在面向对象的设计中处理类的继承关系,并将其映射到数据库中。 首先,我们来理解继承关联关系。在面向...

    Hibernate+中文文档

    5.1.17. 联合子类(union-subclass) 5.1.18. 连接(join) 5.1.19. 键(key) 5.1.20. 字段和规则元素(column and formula elements) 5.1.21. 引用(import) 5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体...

    Hibernate中文详细学习文档

    5.1.17. 联合子类(union-subclass) 5.1.18. 连接(join) 5.1.19. 键(key) 5.1.20. 字段和规则元素(column and formula elements) 5.1.21. 引用(import) 5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体...

    hibernate3.2中文文档(chm格式)

    5.1.17. 联合子类(union-subclass) 5.1.18. 连接(join) 5.1.19. 键(key) 5.1.20. 字段和规则元素(column and formula elements) 5.1.21. 引用(import) 5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体...

    Hibernate 中文 html 帮助文档

    5.1.17. 联合子类(union-subclass) 5.1.18. 连接(join) 5.1.19. 键(key) 5.1.20. 字段和规则元素(column and formula elements) 5.1.21. 引用(import) 5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和...

    hibernate映射配置文件不支持union联合查询[参照].pdf

    在软件开发领域,尤其是...总的来说,当遇到类似问题时,开发者需要仔细检查SQL语句的语法和结构,同时评估是否可以通过调整查询策略、优化数据模型或利用其他工具来避免直接在Hibernate映射文件中使用复杂的子查询。

    hibernate集合的映射

    在Hibernate中,Set通常对应于数据库中的无序且不重复的记录集合,如UNION。例如,一个用户可以有多个电话号码,但每个电话号码都是唯一的。我们可以定义如下映射: ```xml ``` 这里的`&lt;set&gt;`元素定义了一个...

    Hibernate中Criteria的完整用法.docx

    本文将对 Hibernate 中 Criteria 的用法进行总结,涵盖 Criteria 和 DetachedCriteria 的差异、Criterion 和 Projection 的使用方法等。 Hibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口,下面提供...

    HibernateAPI中文版.chm

    5.1.17. 联合子类(union-subclass) 5.1.18. 连接(join) 5.1.19. 键(key) 5.1.20. 字段和规则元素(column and formula elements) 5.1.21. 引用(import) 5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体...

    hibernate_reference中文文档.pdf

    - **1.2.4 值类型的集合**:讨论如何在 Hibernate 中使用集合来表示复杂的数据结构,如 List 或 Set。 - **1.2.5 双向关联**:介绍如何建立和维护对象间的双向引用关系。 - **1.2.6 使双向连起来**:进一步说明如何...

    最全Hibernate 参考文档

    5.1.16. 联合子类(union-subclass) 5.1.17. 连接(join) 5.1.18. 键(key) 5.1.19. 字段和规则元素(column and formula elements) 5.1.20. 引用(import) 5.1.21. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和...

    Hibernate 课件_HQL

    在Hibernate中,通常使用`ThreadLocal`来管理`Session`,确保每个线程拥有自己的`Session`实例,从而避免并发问题。 - **示例**: - 创建一个`ThreadLocal`实例来管理`Session`: - `private static ThreadLocal...

    hibernate 经典题目 其中包括很多核心的题目

    2. Hibernate 应用通常包括四部分:使用 Hibernate API 的程序、配置文件、SessionFactory、Session。缺省的 XML 格式配置文件名为 `hibernate.cfg.xml`,通常放在类路径(classpath)下,其根元素是 `&lt;hibernate-...

    hibernate3.04中文文档.chm

    联合子类(union-subclass) 6.1.17. 连接(join) 6.1.18. 键(key) 6.1.19. 字段和规则元素(column and formula elements) 6.1.20. 引用(import) 6.1.21. any 6.2. Hibernate 的类型 6.2.1. 实体(Entities)和...

    hibernate 体系结构与配置 参考文档(html)

    联合子类(union-subclass) 5.1.18. 连接(join) 5.1.19. 键(key) 5.1.20. 字段和规则元素(column and formula elements) 5.1.21. 引用(import) 5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和...

    Hibernate教程

    联合子类(union-subclass) 6.1.17. 连接(join) 6.1.18. 键(key) 6.1.19. 字段和规则元素(column and formula elements) 6.1.20. 引用(import) 6.1.21. any 6.2. Hibernate 的类型 6.2.1. 实体(Entities)和...

Global site tag (gtag.js) - Google Analytics