使用 Spring+Hibernate 进行测试

Using Spring+Hibernate for testing purposes

我想更清楚地说明我的问题:

  1. 我了解使用 SPring 框架(即容器管理的对象生命周期)和 Hibernate(在 Java 对象和关系数据库系统之间使用 ORM - 阻抗失配解决方案)的目的。

  2. 我了解我们如何自动装配一个对象,并且 Spring 通过查看 applicationContext.xml 文件(除了 persistence.xml 文件(如果使用 Hibernate 或任何其他持久性提供程序)。

我想做的是:

  1. 我想实现自己的购物服务。我已经有了用@Table、@Id、@Column 等注释的实体(项目),以告诉 JPA 这就是将存储在数据库中的内容。

  2. 我已经有一个由 DaoImpl class 实现的 DAO 接口(目前只有添加和删除方法),我在其中完成了以下操作:

    @Repository
    @Transactional
    public class MyShopDbDaoImpl implements MyShopDbDao {
        // The following named unit will be in my persistence.xml file
        // Which will be placed in src/main/resources/META-INF folder
        @PersistenceContext(unitName="myShopDbDao")
        private EntityManager em;
    
        // Getters for em (simply returns em)
    
        // Setters for em (simply assigns an em supplied in the args.)
    
    
        // Other query method
    }
    
  3. 我还有一个 ShopDbController 控制器class,它使用:

    @Autowired
    // defined in the applicationContext.xml file
    private MyShopDbDao myShopDbDaoImpl
    

我苦苦挣扎的是 EntityManagerFactoryEntityManager 的 "Understanding" 关系以及必须如何管理事务。我知道以下层次结构是理解这一点的主要起点:

  1. 客户端与控制器对话。

  2. Controller 映射请求并让 entitymanager 对数据库进行查询和填充(使用 JUNIT 测试等的 test/local 数据库或实际的 SQL 类型数据库).

我所知道的是事务可以手动管理(即开始、提交和关闭会话)或通过 Spring 容器(即在 applicationContext.xml 文件中使用 bean defs)。如何获得有关 entitymanagers 和 entitymanagerfactory 的更多信息以设置我的系统?

我没有发现来自 Oracle/Spring/Hibernate 的联机文档很有帮助。我需要一个例子和解释 entitymanagerfactory、sessionfactory、entitymanager 和 transactionmanager 之间的关系。有人可以帮我解决这个问题吗?

我不需要人牵我的手,只要把我放在正确的方向。我以前做过 Spring 个项目,但从来没有深入了解过一些东西。感谢任何帮助。

非常非常笼统:

  • entitymanagerfactory 是负责创建 entitymanager 的对象,它来自 JPA 规范。
  • SessionFactory 是 entitymanagerfactory 的休眠实现
  • session 是 entitymanager 的休眠实现
  • 事务管理器是当您想手动定义事务时管理事务的对象。

所以如果你想用hibernate,就用SessionFactory和session。如果你想让你留下来 "generic" 使用 EntityManagerFactory。

http://www.javabeat.net/jpa-entitymanager-vs-hibernate-sessionfactory/ http://www.theserverside.com/tip/How-to-get-the-Hibernate-Session-from-the-JPA-20-EntityManager

据我所知,您的 em 引用应该是您数据库的功能代理对象(这个 EntityManager 应该是一个 spring bean,已经配置了所有内容,例如 DB url、驱动程序等。除此之外,您的代码 none 应取决于您拥有的数据库)。你不需要知道你提到的 类 (entitymanagerfactory sessionfactory transactionmanager)。简单的例子是:

List<MyBean> bean = (List<MyBean>)em.createNamedQuery("select * from mydb").getResultList();

运行 select * 查询并直接获取 MyBean 类型的对象应该很容易,无需您进行任何显式转换(这就是 hibernate 的用途)。

与插入相似:

em.persist(myBean);

其中 myBean 是为 Hibernate 注释的东西。

关于事务的简要说明,我发现最好在服务方法上注释@Transactional(你在整个 dao 上做了)。

EntityManagerFactory 将通过 opening/closing 到数据库的新物理连接或使用连接池(c3p0、bonecp、hikari 或您喜欢的任何实现)获得 java.sql.Connection 个对象。在获得一个Connection后,它会用它来创建一个新的EntityManagerEntityManager 可以使用此 Connection 与您的对象和数据库进行交互,并且可以通过调用 EntityManager#getTransaction 然后调用 EntityTransaction#beginEntityTransaction#commit 和 [= 来管理事务20=] 在内部分别与 Connection#beginConnection#commitConnection#rollback 一起工作。这是普通的 JPA,Spring 到目前为止与此无关。

对于事务管理,Spring 通过使用事务管理器帮助您避免手动 opening/closing 事务,特别是一个名为 JpaTransactionManager 的 class。此事务管理器将利用您的 EntityManagerFactory 打开和关闭为一组操作创建的 EntityManager 的事务。这可以使用 XML 配置或 classes/methods 上的 @Transactional 注释来完成。使用这种方法时,您将不再直接使用特定的 classes,而是 Spring 将使用 cglib 为您的 classes 创建代理并使用事务管理器 class 以打开事务,调用您的特定方法并在最后执行提交或回滚,具体取决于您的配置。除此之外,Spring提供了其他配置,如只读事务(不允许数据修改操作)。

这是上面使用 Spring/Hibernate/JPA 解释的元素的基本配置:

<!--
    Declare the datasource.
    Look for your datasource provider like c3p0 or HikariCP.
    Using most basic parameters. It's up to you to tune this config.
-->
<bean id="jpaDataSource"
    class="..."
    destroy-method="close"
    driverClass="${app.jdbc.driverClassName}"
    jdbcUrl="${app.jdbc.url}"
    user="${app.jdbc.username}"
    password="${app.jdbc.password}" />

<!--
    Specify the ORM vendor. This is, the framework implementing JPA.
-->
<bean id="hibernateVendor"
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
    showSql="false"/>

<!--
    Declare the JPA EntityManagerFactory.
    Spring provides a class implementation for it.
-->
<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    persistenceXmlLocation="classpath*:META-INF/persistence.xml"
    persistenceUnitName="hibernatePersistenceUnit"
    dataSource-ref="jpaDataSource"
    jpaVendorAdapter-ref="hibernateVendor"/>

<!--
    Declare a transaction manager.
    Spring uses the transaction manager on top of EntityManagerFactory.
-->
<bean id="transactionManager"
    class="org.springframework.orm.jpa.JpaTransactionManager"
    entityManagerFactory-ref="entityManagerFactory"/>