2009-08-03 128 views
2

我的問題更多的是關於如何實現與Google App Engine的無主關係的最佳實踐問題。我使用JDO做我的堅持,並在谷歌文檔喜歡推薦我堅持我的無主關係的列表,像這樣:實現無主關係Google App Engine

@PersistenceCapable(identityType = IdentityType.APPLICATION) 
public class User implements Serializable, UserDetails { 
... 

    @Persistent 
    private List<Key> groups; 
... 
} 

現在,我在我的困境來到時,我去查詢使用該對象列表他們的關鍵對象。所以,當我得到我的組密鑰列表,以便實際返回組對象列表時,我必須查看該密鑰才能獲取該對象。我的問題是對模型對象進行無主查詢的推薦方式是什麼?

我的模型對象上應該有一個PersistanceManagerFactory的實例,這樣我可以進行查找嗎?

我的模型對象上應該有一個我的GroupDAO對象的實例,所以我可以查找?

我應該有一個工具來做這種查找嗎?

我是新來的,所以我只想知道哪個是最好的方法來做到這一點。謝謝。

回答

1

理想情況下,User對象將有一個返回List<UnownedObject>的方法,以便調用者可以獲得乾淨的API。一種方法是讓User對象具有DAO實例,以便它可以要求DAO執行查詢。

爲了做到這一點,PersistenceManager直到請求結束才能關閉。這樣做的一個方法是創建一個servlet filter

public class PersistenceManagerFilter implements Filter { 
    public void init(FilterConfig filterConfig) throws ServletException { 
    } 

    public void destroy() { 
    } 

    public void doFilter(ServletRequest request, ServletResponse response, 
     FilterChain chain) throws IOException, ServletException { 
    PersistenceManager pm = PMF.get().getPersistenceManager(); 
    try { 
     request.setAttribute("pm", pm); 
     chain.doFilter(request, response); 
    } finally { 
     pm.close(); 
    } 
    } 
} 

然後你就可以注射PersistenceManager到你的DAO。如果你使用Guice你可以這樣做:

@RequestScoped 
public class UserDao { 
    private final PersistenceManager pm; 

    @Inject 
    UserDao(PersistenceManager pm) { 
    this.pm = pm; 
    } 

    public User getUser(parameters) { 
    Key key = createKey(parameters); 
    User user = pm.getObjectById(User.class, key); 
    user.setUserDao(this); 
    return user; 
    } 
} 

這個工作最好時UserDao是在同一個包User所以User.setUserDao()可以包範圍。您可以決定將PersistenceManager設置爲User對象而不是UserDao

接下來,您需要創建一個吉斯模塊綁定PersistenceManager

public class PersistenceManagerModule extends AbstractModule { 
    @Override 
    protected void configure() { 
    } 

    @Provides @RequestScoped 
    PersistenceManager providePersistenceManager(HttpServletRequest request) { 
    return (PersistenceManager) request.getAttribute("pm"); 
    } 
} 

最後,你需要配置Google App Engine to use Guice

這只是一種可能的方式來做到這一點。您可以更聰明地擁有providePersistenceManager創建PersistenceManager並將其存儲爲請求屬性,而不是讓servlet過濾器創建PersistenceManager(過濾器仍將關閉它)。您也可以讓servlet過濾器獲得Guice Injector,這樣您就可以避免使用setAttribute()getAttribute(),而是使用更安全的API。

+0

如果你使用Guice的ServletModule,這更容易,因爲你可以讓Guice將PersistenceManager注入PersistenceManagerFilter,所以你不必使用request.getAttribute()。在這種情況下,PersistenceManagerModule只會調用PMF.get() – NamshubWriter 2009-08-07 00:46:47

1

Google recommends創建一個單例PersistenceManagerFactory。我不會在你的模型中粘貼PMF。

+0

是的,我說錯了。我有一個工廠單身人士,我只是不知道最好是將鍵轉換成實際組。如果我應該在擁有物體或DAO中做到這一點。 – nwallman 2009-08-03 03:28:37