使用 Spring+Hibernate 进行测试
Using Spring+Hibernate for testing purposes
我想更清楚地说明我的问题:
我了解使用 SPring 框架(即容器管理的对象生命周期)和 Hibernate(在 Java 对象和关系数据库系统之间使用 ORM - 阻抗失配解决方案)的目的。
我了解我们如何自动装配一个对象,并且 Spring 通过查看 applicationContext.xml
文件(除了 persistence.xml 文件(如果使用 Hibernate 或任何其他持久性提供程序)。
我想做的是:
我想实现自己的购物服务。我已经有了用@Table、@Id、@Column 等注释的实体(项目),以告诉 JPA 这就是将存储在数据库中的内容。
我已经有一个由 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
}
我还有一个 ShopDbController 控制器class,它使用:
@Autowired
// defined in the applicationContext.xml file
private MyShopDbDao myShopDbDaoImpl
我苦苦挣扎的是 EntityManagerFactory
和 EntityManager
的 "Understanding" 关系以及必须如何管理事务。我知道以下层次结构是理解这一点的主要起点:
客户端与控制器对话。
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
后,它会用它来创建一个新的EntityManager
。 EntityManager
可以使用此 Connection
与您的对象和数据库进行交互,并且可以通过调用 EntityManager#getTransaction
然后调用 EntityTransaction#begin
、EntityTransaction#commit
和 [= 来管理事务20=] 在内部分别与 Connection#begin
、Connection#commit
和 Connection#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"/>
我想更清楚地说明我的问题:
我了解使用 SPring 框架(即容器管理的对象生命周期)和 Hibernate(在 Java 对象和关系数据库系统之间使用 ORM - 阻抗失配解决方案)的目的。
我了解我们如何自动装配一个对象,并且 Spring 通过查看
applicationContext.xml
文件(除了 persistence.xml 文件(如果使用 Hibernate 或任何其他持久性提供程序)。
我想做的是:
我想实现自己的购物服务。我已经有了用@Table、@Id、@Column 等注释的实体(项目),以告诉 JPA 这就是将存储在数据库中的内容。
我已经有一个由 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 }
我还有一个 ShopDbController 控制器class,它使用:
@Autowired // defined in the applicationContext.xml file private MyShopDbDao myShopDbDaoImpl
我苦苦挣扎的是 EntityManagerFactory
和 EntityManager
的 "Understanding" 关系以及必须如何管理事务。我知道以下层次结构是理解这一点的主要起点:
客户端与控制器对话。
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
后,它会用它来创建一个新的EntityManager
。 EntityManager
可以使用此 Connection
与您的对象和数据库进行交互,并且可以通过调用 EntityManager#getTransaction
然后调用 EntityTransaction#begin
、EntityTransaction#commit
和 [= 来管理事务20=] 在内部分别与 Connection#begin
、Connection#commit
和 Connection#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"/>