如何使用JDO持久性管理器?

关于如何创建/使用JDO持久性管理器(PM,以下简称),我有两个问题。

比如,在Java Web应用程序中,如果我有10个实体,可以在逻辑上分组为2个组(例如,5个用户相关实体和5个业务相关实体)

  1. 我是否需要两个不同的PM来管理这两个组,或者只有一个PM就足够了?
  2. 关于初始化,我应该使用PM的单例实例(所有用户在给定时间点使用应用程序共享)还是应该为每个会话创建PM?

根据JDO文档,您可以为每个数据存储区创建一个PersistenceManagerFactory 。 如果您使用JDO通过SQL访问数据库并且您有多个数据库,则每个数据库需要一个PersistenceManagerFactory (因为您需要在创建PersistenceManagerFactory时指定JDBC URL,用户名和密码)。

对于简单的用例,您可以在需要时创建PersistenceManager并在finally子句中关闭它(请参阅持久性管理器文档 )。

如果您使用事务,并且更新实体的代码可以分布在多个方法或对象上,我建议您按需创建PersistenceManager并将其存储在ThreadLocal (如果您使用Guice或Spring,则存储在请求范围的对象中)。 这将确保执行更新的任何代码都参与当前事务。 确保在请求结束时关闭PersistenceManager

如果您只需要一个持久性管理器工厂,则可以执行以下操作:

 public class Datastore { private static PersistenceManagerFactory PMF; private static final ThreadLocal PER_THREAD_PM = new ThreadLocal(); 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这样的dependency injection框架,我会将这些方法设置为非静态,并将Datastore绑定为Singleton。

你可以在Servletfilter中调用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(); } } }