您的位置:首页 > 其它

Hibernate实战_笔记10

2014-03-08 13:27 363 查看

使用Hibernate EntityManager

Hibernate EntityManager是围绕提供JPA编程接口的Hibernate Core的一个包装,支持JPA实体实例的生命周期,并允许你用标准的Java Persistence查询语言编写查询。由于JPA功能是Hibernate原生能力的一个子集。你给Hibernate EntityManager配置了项目,马上就会看到一种特殊的简化:你不再非得在配置文件中列出所有被注解的类(或者XML映射文件)了。

1、基本的JPA配置

SessionFactory在Hibernate应用程序中表示一个特定的逻辑数据存储配置。EntityManagerFactory在JPA应用程序中扮演着同样的角色,你用配置文件或者在应用程序代码中配置EntityManagerFactory(EMF),就像配置SessionFactory一样。EMF的配置,与一组映射元数据(通常是被注解的类)一起,被称作持久化单元(persistence unit)。

<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">
<persistence-unit name="helloworld">
<properties>
<property name="hibernate.ejb.cfgfile" value="/hibernate.cfg.xml" />
</properties>
</persistence-unit>
</persistence>
和一个持久化单元都需要一个名称,在这个例子中为helloworld。

使用任意数量的属性对持久化单元进行进一步设置,这些属性全是特定于供应商的。前一个例子中的属性hibernate.ejb.cfgfile,就像是一个杂物箱。它引用包含着这个持久化单元所有设置的hibernate.cfg.xml文件(在类路径的根目录中)——你正在重用现有的Hibernate设置。随后,将把所有的配置细节移进persistence.xml文件,但是现在你更关注使用JPA运行“Hello World“。

<property name="src.etc.dir" value="etc" />
<!--复制xml、properties后缀文件到bin目录-->
<target name="copymetafiles">
<copy todir="${build.dir}">
<fileset dir="${src.java.dir}">
<patternset refid="meta.files" />
</fileset>
</copy>
<copy todir="${build.dir}">
<fileset dir="${src.etc.dir}">
<patternset refid="meta.files" />
</fileset>
</copy>
</target>
firstJta/etc目录下与meta.files模式相匹配的所有内容都被复制到构建输出目录,这是运行时classpath的一部分。

2、使用JPA的“Hello World”

Java Persistence中主要的编程接口:

1、javax.persistence.Persistence——给EntityManagerFactory的创建提供一种静态方法的一个启动类。

2、javax.persistence.EntityManagerFactory——等同于Hiberante Session。这个单线程、非共享的对象表示数据访问的一个特定工作单元。它提供方法去管理实体实例的生命周期并创建Query实例。

3、javax.persistence.Query——等同于Hibernate Query。这个对象是一种特定的JPA查询语言或者原生的SQL查询表示法,它允许参数的安全绑定,并给查询的执行提供各种各样的方法。

4、javax.persistence.EntityTransaction——等同于Hibernate Transaction,在Java SE环境中用于RESOURCE_LOCAL事务的划分。在Java EE中,依赖JTA标准的javax.transaction.UserTransaction接口进行编程式的事务划分。

要使用JPA接口,需要复制必要的库到firstJta/lib目录下

我使用的

Hibernate版本 Hibernate 3.2.5

Hibernate EntityManager 3.2.1.GA

Hibernate Annotations 3.2.1.GA

如果你的Hibernate是3.5之后,Hibernate Core、Hibernate EntityManager、Hibernate Annotations又集成了,就不会有Jar冲突等等问题。

package cn.jbit.jta.util;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public final class JPAUtil {

private static final EntityManagerFactory emf;

static {
try{
emf = Persistence.createEntityManagerFactory("helloworld");
}catch(Throwable ex){
throw new ExceptionInInitializerError(ex);
}
}

private JPAUtil(){
}

public static EntityManagerFactory getEmf() {
return emf;
}

public static EntityManager getEntityManager(){
return emf.createEntityManager();
}

public static void shutdown(){
emf.close();
}
}
package cn.jbit.jta.test;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

import cn.jbit.jta.entity.Message;
import cn.jbit.jta.util.JPAUtil;

public class EntityManagerTest {

@SuppressWarnings("unchecked")
public static void main(String[] args) {
// 第一个单元
// createEntityMangaerFacoty参数"helloworld"是persistence.xml文件中持久化单元名称
EntityManager em = JPAUtil.getEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

Message message = new Message("Hello World");
em.persist(message);

tx.commit();
em.close();

// 第二个单元
EntityManager secondEm = JPAUtil.getEntityManager();
EntityTransaction secondTx = secondEm.getTransaction();
secondTx.begin();

List<Message> messages = secondEm.createQuery(
"select m from Message m order by m.text asc").getResultList();
System.out.println(messages.size() + "条消息记录");
for (Message m : messages) {
System.out.println(m.getText());
}
secondTx.commit();
secondEm.close();

JPAUtil.shutdown();
}
}
在这段代码中你可能注意到的第一点是不再有Hibernate导入,只有javax.persistence.*。用一个对persistence的静态调用和持久化单元的名称来创建EntityManagerFactory。其余代码应该是不言自明的——就像使用Hibernate一样使用JPA,虽然在API中有些小差别,并且方法的名称也略有不同。

3、元数据的自动侦测

之前我们承诺过你将不一定要设置中列出所有被注解的类或者XML映射文件,但是它们仍然在hibernate.cfg.xml中。其实不只是从hibernate.cfg.xml中移除这个单独的不必要选项,而是要移除整个文件,并把所有的配置细节移到persistence.xml里面。

完整的持久化单元配置文件

<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">
<persistence-unit name="helloworld">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!--
<class>cn.jbit.jta.entity.Message</class> -->
<properties>
<!--
<property name="hibernate.ejb.cfgfile" value="/hibernate.cfg.xml" /> -->
<property name="hibernate.archive.autodetection" value="class,hbm"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver"/>
<property name="hibernate.connection.url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<property name="hibernate.connection.username" value="system"/>
<property name="hibernate.connection.password" value="bdqn"/>
<property name="hibernate.c3p0.min_size" value="5"/>
<property name="hibernate.c3p0.max_size" value="20"/>
<property name="hibernate.c3p0.timeout" value="300"/>
<property name="hibernate.c3p0.max_statements" value="50"/>
<property name="hibernate.c3p0.idle_test_period" value="3000"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
</persistence>
在这个配置文件中有3个值得关注的新元素,首先,你设置了应该为这个持久化单元所用的一个显式的<provider>。通常只在你在非Java EE的环境中部署,规范要求列出包含<class>元素的所有被注解的类——Hibernate处处支持映射元数据的自动侦测,使它变成可选。最后Hibernate配置设置hibernate.archive.autodetection告知Hibernate要自动扫描哪些元数据:被注解的类(class)和Hibernate XML映射文件(hbm)。默认情况下,Hibernate
EntityManager对两者都进行扫描。

被注解的类和XML映射文件的自动侦测是JPA一个很棒的特性。通常只在有Java EE应用程序服务器中才可用;至少,这是EJB3.0规范保证的东西。但是,Hibernate作为一个 JPA提供程序,也在简单的Java SE中实现它,虽然你也许不能够使用与任何其他JPA提供程序完全相同的配置。

所有的JPA配置设置都捆绑在persistence.xml中,所以的映射元数据都包括在Message类的Java源代码中,Hibernate在启动时自动扫描并找到元数据。相较于纯粹的Hibernate,现在你这些好处:

1)被部署元数据的自动扫描,这在大项目中是个重要的特性。如果几百个实体由一个大团队开发时,维护一系列被注解的类或者映射文件变得很困难。

2)标准的和简化的配置,配置文件有标准的位置,以及一个部署概念——持久化单元——在一个应用程序文档(EAR)中包有几个单元(JAR)的更大项目中,它有着更多的优势。

3)标准的数据访问代码、实体实例的生命周期和完全可移植的查询。应用程序中没有私有的导入。

这些仅仅是JPA的其中一些优势。如果你把它与完全的EJB3.0编程模型和其他的托管组件结合起来,就会看到它真正的威力。

代码提供下载

JPA项目链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: