理想情况下,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。
如果你使用Guice的ServletModule,这更容易,因为你可以让Guice将PersistenceManager注入PersistenceManagerFilter,所以你不必使用request.getAttribute()。在这种情况下,PersistenceManagerModule只会调用PMF.get() – NamshubWriter 2009-08-07 00:46:47