【发布时间】:2013-07-10 16:58:08
【问题描述】:
在我的表中,Person 对象可以与其他人有关系。我想做一个递归过程,返回一个人的关系,然后是关系的关系等等。
我有一个包含两列的表格,Person 和 PersonRelation。
PERSON PERSON_RELATION
id id
name person_id
age relation_id
relation_type
在我的 PersonBeanImpl 中,我有一个方法可以返回一个人的关系列表以及他们的关系等等(recusrivly):
public List<Person> getPersonRelationsAndTheirRelations(int personId) {
List<Person> relations = new ArrayList<>();
getRelationsRecursivly(relations, personId);
return relations;
}
private void getRelationsRecursivly(List<Person> relations, int personId) {
relations.addAll(fetchPersonRelation(personId));
for(Person p : relations){
getRelationsRecursivly(relations, p.getId());
}
}
public List<Person> fetchPersonRelation(int personId) {
String sql = "SELECT p FROM Person p, PersonRelation pr WHERE pr.relationId = p.Id AND pr.personId = :personId";
Query query = entityManager.createQuery(sql);
query.setParameter(":personId", personId);
return query.getResultList();
}
此代码有效,但完成事务需要大量时间,因为方法fetchPersonRelation() 被多次调用。
是否可以仅使用 SQL 递归地完成所有操作?我正在使用 PostgreSQL。
SQLFiddle 示例:http://sqlfiddle.com/#!12/c1f32/3
【问题讨论】:
-
是的,您可以使用以下任何一种:for 循环、while 循环和 sql 中的游标。
-
这在 SQL 中是不可能的。最好的方法是使用
JOINs 在单个查询中检索所有数据,并按您需要关联的值对其进行排序,然后在您的Java 代码中手动处理它。这将至少快 10 倍。 -
@ShreyosAdikari 您可以在特定于服务器的 SQL 附加项中使用它们(例如 PLPGSQL/Transact-SQL),但它们不是 ANSI SQL 标准的一部分。
-
您更改 Person 和 PersonRelation 表的顺序以减少时间成本。
-
@LuiggiMendoza:您能否提供一个示例,说明如何使用
joins进行递归调用。
标签: java sql postgresql entitymanager recursive-query