为Hibernate设计对象

时间:2010-02-09 19:21:08

标签: hibernate object

我需要一些设计问题的帮助。我无法绕过如何设计对象(或者可能是多个对象),以便我可以按照我想要的方式进行查询。

首先让我展示一个返回我想要的信息的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";

老实说,我甚至不知道那里的幕后是否有连接,但我知道这给了我原本想要的信息。如果有人建议如何更有效地进行此查询,请告诉我。

2 个答案:

答案 0 :(得分:1)

  

如果知道,receiver_guid和   giver_guid都是(都可以)   多对一的映射   user_info.guid。 user_info.guid是   pk在那张桌子上; pk on   rights_table是另一列没有   这里提到。

我会尝试以下内容:

  • 用户与正确的实体之间存在一对多关系“rightsGiven”。
  • 用户与正确的实体之间存在一对多关系“rightsReceived”。
  • 权利与用户之间具有“给予”的一对一关系。
  • 权利与用户“给予”一对一的关系。

要获取用户X获得某些权限的用户列表,请

  • 加载用户X
  • 遍历权利集合“righstGiven”
  • 为每个权利获得“givenTo”用户

一旦你加载了对象,当你遍历图形时,休眠会懒洋洋地为你加载对象。这可能导致许多查询在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, ...)
  • RightsAssingment
    (id, giver_id, reciever_id, right_id, date, info...)

这种方式将RightsAssignment(请原谅名称,将其更改为适合的名称)是用户对另一个用户的权利分配,以及上面的assignment.date字段之类的可选附加信息(您现在可能不需要它,但它使你的模型更具扩展性。) RightsAssignment中的字段在给定者,接收者和右边都有一个ManyToOne,其中User和Right将通过RightsAssignment中的字段映射OneToMany。

要获取任何一个用户分配的权限列表,您只需在RightsAssignment表中查询giver_id与user.id匹配的条目。

希望这有帮助!