根据JDO Documentation,您为每个数据存储创建一个PersistenceManagerFactory。如果您使用 JDO 通过 SQL 访问数据库并且您有多个数据库,那么每个数据库需要一个 PersistenceManagerFactory(因为您需要在创建 PersistenceManagerFactory 时指定 JDBC URL、用户名和密码) .
对于简单的用例,您可以在需要时创建一个PersistenceManager,然后在finally 子句中关闭它(参见the persistence manager documentation)。
如果您使用事务,并且更新实体的代码可以分布在多个方法或对象中,我建议按需创建 PersistenceManager 并将其存储在 ThreadLocal 中(如果您使用 Guice,则将其存储在请求范围的对象中或弹簧)。这将确保执行更新的任何代码都参与当前事务。确保在请求结束时关闭PersistenceManager。
如果你只需要一个持久化管理器工厂,你可以这样做:
public class Datastore {
private static PersistenceManagerFactory PMF;
private static final ThreadLocal<PersistenceManager> PER_THREAD_PM
= new ThreadLocal<PersistenceManager>();
public static void initialize() {
if (PMF != null) {
throw new IllegalStateException("initialize() already called");
}
PMF = JDOHelper.getPersistenceManagerFactory("jdo.properties");
}
public static PersistenceManager getPersistenceManager() {
PersistenceManager pm = PER_THREAD_PM.get();
if (pm == null) {
pm = PMF.getPersistenceManager();
PER_THREAD_PM.set(pm);
}
return pm;
}
public static void finishRequest() {
PersistenceManager pm = PER_THREAD_PM.get();
if (pm != null) {
PER_THREAD_PM.remove();
Transaction tx = pm.currentTransaction();
if (tx.isActive()) {
tx.rollback();
}
pm.close();
}
}
}
任何需要持久化管理器的代码都可以调用Datastore.getPersistenceManager()
注意:为了回答您的问题,我使用了所有静态方法使其变得简单。如果我使用像 Guice 这样的依赖注入框架,我会将方法设为非静态并将 Datastore 绑定为 Singleton。
您可以在 Servlet 过滤器中调用 finishRequest:
public class PersistenceManagerFilter implements javax.servlet.Filter {
public init(FilterConfig filterConfig) {
Datastore.initialize();
}
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {
chain.doFilter(request, response);
} finally {
Datastore.finishRequest();
}
}
}