Hibernate实战_笔记10

使用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编程模型和其他的托管组件结合起来,就会看到它真正的威力。

代码提供下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值