[英]Datanucleus creates subquery instead of join
我有這些注釋:
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)
我試圖給數據核一個注釋,告訴它在數據庫SELECT a.* FROM accounts a JOIN users u on a.id = u.user_id where u.id = 23
上運行。FROM 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);
您正在執行Query
只是為了獲得一個對象,這是非常低效的。 相反,您可以輕松地做到
User u = pm.getObjectById(User.class, 1);
這很可能總共發出2條SQL; 1獲取基本用戶對象,1獲取與該用戶連接的帳戶。 不會有EXISTS子句。
關於您實際在做什么。 發出查詢。 查詢是常規的,在大多數用例中將返回多個對象。 查詢的filter子句可能很復雜。 查詢被轉換為SQL以獲取基本的用戶字段。 它無法在一次調用中獲取相關對象,因此您的日志可能會講一些關於BULK FETCH的信息 (或類似的東西,無論DataNucleus稱之為什么)。 這將具有EXISTS
子句,其中EXISTS
子查詢將第二個查詢限制為該查詢所適用的對象。 他們這樣做是為了避免N + 1問題。 通常,使用EXISTS
最適合查詢的一般情況。 在您的特定情況下,最好使用INNER JOIN
,但是我認為當前不支持將其作為BULK FETCH選項。 他們的代碼是開源的,我知道他們過去曾要求人們在需要替代處理的地方做出貢獻……因此,如果您想在這種精確的情況下使用查詢,則可以做出貢獻。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.