簡體   English   中英

Datanucleus創建子查詢而不是聯接

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM