简体   繁体   English

休眠标准离开了我们

[英]Hibernate criteria left our join

I have the following entities: 我有以下实体:

Machines {
   id,
   name
}

Favorites {
  userId,
  objectId,
  objectType
}

Now I want to return list of machines ordered by favorites, name. 现在,我想返回按收藏夹排序的机器列表,名称。

Favorites does not have any relation with Machines entities, its a generic entity which can hold various favoritable objects. 收藏夹与Machines实体没有任何关系,它是可以容纳各种收藏对象的通用实体。

I got the sorting to work by the following raw sql. 我通过以下原始sql进行排序。 Is there any way to get this working using hibernate criterias. 有没有什么办法可以使用休眠标准来使其正常工作。 Basically ability to add alias for Favorites though Machines doesn't have any reference to it. 基本上可以为“收藏夹”添加别名,尽管“机器”没有任何引用。

select m.* from Machines m left outer join Favorites f on m.id=f.objectId and f.userId =@userId order by f.userId desc, m.name asc

There are two ways to do this: 有两种方法可以做到这一点:

  1. Use an SQL query or an SQL restriction for a criteria query. 对条件查询使用SQL查询或SQL限制
  2. Map the relation between Favorites and Machines as an Any type association . 将“收藏夹”和“机器”之间的关系映射为Any类型关联

Since you already have the query, executing it as a native SQL query through hibernate is the simplest solution: 由于您已经有了查询,因此通过hibernate作为本地SQL查询执行查询是最简单的解决方案:

sess
  .createSQLQuery("SELECT ... ")
  .addEntity(Machine.class)
  .list();

The Any type association however, will probably benefit you in other situations where you want to query favoritables. 但是,在要查询收藏夹的其他情况下,“任何类型”关联可能会使您受益。

As said by @Maarten Winkels, you can use native SQL query that you have. 如@Maarten Winkels所说,您可以使用已有的本机SQL查询。 You can do that but, if you want change your database then syntax may differs. 您可以这样做,但是,如果要更改数据库,则语法可能会有所不同。 So, it is recommended not to use native SQL query. 因此, 建议不要使用本机SQL查询。

You cannot perform outer join using Hibernate criteria without any association between tables. 没有表之间的任何关联,就不能使用Hibernate条件执行外部联接。 If you change your mind & want to add an association between these tables, then You can do something like below using criteria 如果您改变主意并想在这些表之间添加关联,则可以使用条件执行以下类似操作

List machines = session.createCriteria( Machines.class )
                    .createAlias("Machines", "m")
                    .createAlias("Favorites", "f", Criteria.LEFT_JOIN, 
                                Restrictions.and(Restrictions.eq("m.id", "f.objectId"),
                                Restrictions.eq("f.userId", "@userId")))
                    .addOrder(Order.desc("f.userId"))
                    .addOrder(Order.asc("m.name"))
                    .list();

If for some reason you don't want to add any relationship between these tables, then you can use INNER JOIN or CROSS JOIN to get all machines with whatever criteria you want. 如果由于某种原因您不想在这些表之间添加任何关系 ,则可以使用INNER JOIN或CROSS JOIN来获取所有具有所需条件的计算机。

from Machines m, Favorites f where m.id = f.objectId and f.userId = @userId order by f.userId desc, m.name asc; 

With inner joins there is one problem, if there is outer join relation in database then it doesn't work. 对于内部联接,存在一个问题,如果数据库中存在外部联接关系,则它不起作用。

You can also write subqueries or separate queries & perform manual conditional checks between the results returned by those queries. 您还可以编写子查询单独的查询,并在这些查询返回的结果之间执行手动条件检查。

And one thing I want to ask you, What is the meaning of @userId in your SQL query ? 我想问你一件事,@ userId在您的SQL查询中是什么意思? I keep it as it is in my answer but, I didn't understand for what purpose @ is there ? 我将其保留为我的答案,但是,我不知道@有什么用途?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM