JPA Guice的JPA持久化

Java Persistence API (JPA)

JPA 是个标准发布的JSR-220 (或 EJB3)的一部分. 大致与HIbernate或者Oracle的TopLink相同; 他们也是很多重要JPA的实现中的2个。. Guice 的持久化支持与厂商无关, 所以如果你需要的话它很容易在不同的实现(如Appengine's datastore)中进行切换。

启用持久化支持(Enabling Persistence Support)

简单的安装JPA模块( JPA module)就可以启用持久化支持
Injector injector = Guice.createInjector(..., new JpaPersistModule("myFirstJpaUnit"));
在JPA中, 在位于META-INF下配置你的persistence.xml文件,或者在classpath中(如果文件在jar中,那么此文件应该jar的根目录中) . 在这个文件中要大概的声明一些持久化单元,这些单元可能在不同的环境中(例如位于不同的数据库中),这里是一个简单的JPA配置的例子 :
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">

        <!-- A JPA Persistence Unit -->
        <persistence-unit name="myFirstJpaUnit" transaction-type="RESOURCE_LOCAL">
                <provider>org.hibernate.ejb.HibernatePersistence</provider>
 
                <!-- JPA entities must be registered here -->
                <class>com.wideplay.warp.jpa.JpaTestEntity</class>

                <properties>
                        <!-- vendor-specific properties go here -->
                </properties>
        </persistence-unit>

</persistence>
告诉Guice持久化模块你要使用哪些持久化单元,在创建你的模块时你需要指定这些单元的名称:
Injector injector = Guice.createInjector(..., new JpaPersistModule("myFirstJpaUnit"));
最后,你必须决定持久化服务何时启动(调用PersistService的start()方法)。 .我通常用一个简单的启动类(initalizer)在我需要的时机来触发:
public class MyInitializer { 
        @Inject MyInitializer(PersistService service) {
                service.start(); 
 
                // At this point JPA is started and ready.
        } 
}
在你的应用中用Guice API启动所有的服务(service)非常有意义,建议您思考把它(启动持久化服务)如何应用到您特有的开发环境中。
不过,在web应用中,如果你使用PersistFilter 的话则不需要做其他事情(往下看)。
非常流行的策略是: JPA  EntityManager创建和销毁于每个数据库事务中开始和结束点。在持久化单元的配置中设置 transaction-type属性:
 <persistence-unit name="myFirstJpaUnit" transaction-type="RESOURCE_LOCAL">

在事务中使用EntityManager

一旦你注入器被创建,你以在你的持久化服务中任意注入和使用EntityManager :

import com.google.inject.persist.Transactional;
import javax.persistence.EntityManager; 
 
public class MyService {
        @Inject EntityManager em; 
 
        @Transactional 
        public void createNewPerson() {
                em.persist(new Person(...)); 
        } 
}

这是已知的session-per-transaction策略. 如果想了解更多关于事务和工作单元的信息,可以看“这里”.

注意:如果你为MyService加上 @Singleton注解,那么你需要使用Provider<EntityManager>方式进行注解来替换现在的方式。

Web环境(每请求一个会话) (session-per-http-request)

到此为止,我们已经看到 ssion-per-transaction策略。在web环境中这不是典型的方式,通常的方式是每个http请求为一个会话更好(也叫open-session-in-view).启用这种策略,你首先需要在ServletModule中增加一个filter:
public class MyModule extends ServletModule {
  protected void configureServlets() {
    install(new JpaPersistModule("myJpaUnit"));  // like we saw earlier.

    filter("/*").through(PersistFilter.class);
  }
}

你需要在加载使用 EntityManager  的其他模块之前首先加载这个filter。注意使用这个配置你可以使用同一个 EntityManager  运行多个事务(例如同一个Http请求)



你可能感兴趣的:(java,jpa,Guice)