我需要一些设计问题的帮助。我无法绕过如何设计对象(或者可能是多个对象),以便我可以按照我想要的方式进行查询。
首先让我展示一个返回我想要的信息的SQL查询:
select distinct rights_table.receiver_guid, user_info.name
from rights_table
inner join user_info
on rights_table.receiver_guid = user_info.guid
where rights_table.giver_guid = '_this_is_the_argument_'
因此user_info为每个用户都有一个条目。 rights_table包含有关giver_guid委派给receiver_guid的权限的信息。我现在不关心权利是什么 - 我只是想能够拿一个giver_guid并找回他所有权利的任何人的所有guid和名字的清单。我无法概念化如何将这些表转换为对象模型,以便我可以执行该查询。
如果知道的话,receiver_guid和giver_guid都是(可能都是)与user_info.guid的多对一映射。 user_info.guid是该表上的pk; right_table上的pk是另一个未在此处提及的列。
编辑:我的解决方案:
正如Tim建议的那样,我在权限表“object”上放置了多对一映射,将权限表链接到User表。我花了一段时间才明白,当你做这样的映射时,Hibernate确实会加入你的隐私,所以这就是我基本上为HQL做的事情:
String hqlQuery =
"select right.recipient_guid, user.name " +
"from rightsTable right, userInfo user " +
"where right.recipient_guid = user.guid and right.giver_guid like :giver_guid";
老实说,我甚至不知道那里的幕后是否有连接,但我知道这给了我原本想要的信息。如果有人建议如何更有效地进行此查询,请告诉我。
答案 0 :(得分:1)
如果知道,receiver_guid和 giver_guid都是(都可以) 多对一的映射 user_info.guid。 user_info.guid是 pk在那张桌子上; pk on rights_table是另一列没有 这里提到。
我会尝试以下内容:
要获取用户X
获得某些权限的用户列表,请
X
一旦你加载了对象,当你遍历图形时,休眠会懒洋洋地为你加载对象。这可能导致许多查询在hibernate下执行,尤其是Select N+1问题。然后使用eager getching,以便hibernate使用一个连接。例如。 @OneToMany(fetch = FetchType.EAGER)
。设置对“rightsGiven”和“givenTo”的热切提取。
然后,您可以控制所谓的max fetch depth,以确保hibernate不会急切地加载整个图表。在这种情况下,我们需要急切地获取2个关系(rightsGiven + givenTo),因此将其设置为2.这应该导致使用两个外部联接进行查询。
答案 1 :(得分:1)
尝试将查询和表映射到对象很难,因为概念模型差异很大。将您的SQL语句放在一边,只是根据您要推断的数据进行处理,我得出以下对象:
(id, name, Set< RightsAssignment> rights_given, Set< RightsAssignment> rights_recieved, info, ...)
(id, name, level, Set< RightsAssignment> assignments, info, ...)
(id, giver_id, reciever_id, right_id, date, info...)
这种方式将RightsAssignment(请原谅名称,将其更改为适合的名称)是用户对另一个用户的权利分配,以及上面的assignment.date字段之类的可选附加信息(您现在可能不需要它,但它使你的模型更具扩展性。) RightsAssignment中的字段在给定者,接收者和右边都有一个ManyToOne,其中User和Right将通过RightsAssignment中的字段映射OneToMany。
要获取任何一个用户分配的权限列表,您只需在RightsAssignment表中查询giver_id与user.id匹配的条目。
希望这有帮助!