我有一些巫师,他们分别属于魔术的各个分支。成为一个教派的成员会赋予您特殊的能力,您可以使用这些能力来打败敌人。这些教派中的一些教派具有一些教派,这些教派会赋予您其他权力。
@Entity
public class Sect {
private long id;
private String name;
private Sect parent;
@ManyToMany
private Set<Spell> spells;
}
@Entity
public class Wizard {
private long id;
private String name;
@ManyToMany
private Set<Sect> sects;
}
现在,我有一个巫师,他是橡树勋章的成员。橡树顺序是森林顺序的一个分支,森林顺序又是地球顺序的一个分支。 (因此
wizard.sects.contains(oak) == true
和oak.parent.parent.equals(earth) == true
)。 “地球螺栓”法术是由地球之王授予的。我的巫师不是地球秩序,甚至不是森林秩序的成员。他是橡树勋章的成员之一。但是,他暗中是会员,并且可以使用所有这些咒语。现在,我基本上是在这样做:boolean canCast(Wizard wizard, Spell spell) {
Queue<Sect> toProcess = new ...
toProcess.addAll(wizard.getSects());
Set<Sect> processed = new ...
while(!toProcess.isEmpty()) {
Sect sect = toProcess.poll();
if(!processed.add(sect)) continue; // already did this from a sister sect
toProcess.add(sect.getParent());
if(sect.getSpells().contains(spell))
return true;
}
return false;
}
但是,当我真的不需要时,将所有这些信息都拉回来似乎很愚蠢。
我知道我有几种选择,例如保留一张父级订单表,因此当您被添加到橡树勋章中时,它会将您添加到森林勋章和地球勋章中,但这似乎很奇怪。如果您被从橡树勋章中删除并删除了森林和地球,将很难管理事情。如果您也是枫木勋章的一部分怎么办?您仍然会在森林和地球中。那只是一种情况-我敢肯定,在很多情况下,这种情况会在我的脸上爆炸。
另一种选择是跟踪来自地球和森林的咒语,并将其放入橡树和枫树。但是,如果橡树明确提供了在地球上也能找到的咒语,该怎么办?如果我从地球教学中删除它,则不应将其从Oak中删除。所以我真的会在Spell类上引用Sect,然后将它们全部添加到Sect和子分区中。但这似乎也需要大量维护,并且容易出错。
另一种选择是保留整个拼写提供结构的缓存,并且只要产品中的某些内容发生变化,只需清空表并对其进行重构。当我编辑咒语产品时,这将是一项昂贵的操作,但这是相当罕见的情况。
理想情况下,我有一个运行并获取所需信息的HQL(我想我可以做NamedNative ...,但要避免的话)。但是我不知道如何构造这样的查询,如果我这样做了,那么如何使其不能完全糟透了。
我有没有想到的选择?有什么工具或技巧吗?我知道休眠有很多技巧!
最佳答案
编写Sect时,添加一个方法
isSubsectOf(Sect s)
如果此教派是其他教派的一个教派,则返回true。它是递归的,因此它返回aprent sec,祖父母宗派等。现在您可以通过以下方式检查向导是否是该宗派的成员:
测试他是否直接是该教派的成员
测试他所属的教派是否是它的一个分支
为了完整起见,您可能还想写一些列出给定宗派的所有父项等。
要检查能力,请在Sect'canCast(Spell sp)'上编写一个方法,该方法不仅检查它是否在该Sect的咒语列表中,而且还检查所有父Sect。如果canCast(Spell sp)对于特定成员所属的Sect返回true,则向导可以施放咒语。
这是直接的Java继承,不需要任何复杂的操作
关于java - 分层所有权导致请求缓慢,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20008900/