Datanucleus创建子查询而不是连接

时间:2017-03-06 16:26:07

标签: java orm datanucleus

我有这些注释:

public class Account {
@Persistent(defaultFetchGroup = "true", dependent = "false")
@Column(name = "user_owner_id")
private User user;
} 

public class User {
@Persistent(defaultFetchGroup = "true", mappedBy = "user")
@Element(column = "user_owner_id", dependent = "true")
private Set<Account>      accounts;
}

启动Account类时,对数据库的查询使用SELECT * FROM accounts where exists (SELECT id from users where id=23)

我正在尝试为datanucleus提供一个注释,告诉它在数据库SELECT a.* FROM accounts a JOIN users u on a.id = u.user_id where u.id = 23上运行,因为这更为理想。

那么我应该使用哪个注释来使数据核改变其查询形式?

---另外----

这是我们如何检索数据的简化版本:

PersistenceManager persistenceManager = persistenceManagerFactory.getPersistenceManager();
      persistenceManager.getFetchPlan().setMaxFetchDepth(FetchPlan.FETCH_SIZE_GREEDY);

Query query = persistenceManager.newQuery("javax.jdo.query.JDOQL", null);

query.setClass(User.class);
query.setFilter("this.uuid==p1");
query.declareParameters("java.lang.String p1");

final List<E> entities = (List<E>) query.execute(uuid);

E entity = entities.iterator().next();

return persistenceManager.detachCopy(entity);

1 个答案:

答案 0 :(得分:2)

您正在执行Query只是为了获得一个对象,效率非常低。相反,你可以轻松做到

User u = pm.getObjectById(User.class, 1);

这可能会发出2个SQL; 1获取基本User对象,1获取连接到该用户的Accounts。没有EXISTS条款。

关于你实际在做什么。发出查询。查询是通用的,在大多数用例中,将返回多个对象。查询的filter子句可能很复杂。 Query被转换为SQL以获取基本的User字段。它无法在一次调用中获取相关对象,因此您的日志可能会说明 BULK FETCH (或类似的东西,无论DataNucleus调用它)。这将有EXISTS子句,EXISTS子查询将第二个查询限制为Query应用的对象。他们这样做是为了避免N + 1问题。通常,使用EXISTS最适合查询的一般情况。在您的具体情况下,拥有INNER JOIN会很不错,但我不认为目前支持 BULK FETCH 选项。他们的代码是开源的,我知道他们已经要求人们过去在他们想要替代处理的地方做出贡献......所以如果你想在这种精确的情况下使用查询,你可以贡献一些东西。