spring生成EntityManagerFactory的三种方式

1.LocalEntityManagerFactoryBean
只是简单环境中使用。它使用JPA PersistenceProvider自动检测机制( according to JPA‘s Java SE bootstrapping ),并且大多数情况下,你只能定义一下persistence unit name

例如:

<beans>
<bean id="myEmf" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="myPersistenceUnit"/>
</bean>
</beans>
2.从JNDI获取EntityManagerFactory
这个选项是当你应用发布在javaee5的服务器中。你可以参阅自己应用服务器文档,如何发布一个自定义的JPA provider到你的应用服务器中。

例:

<beans>
<jee:jndi-lookup id="myEmf" jndi-name="persistence/myPersistenceUnit"/>
</beans>
当javaee服务器启动时,会自动检测persistence units。实际上,是检测应用包中的META-INF/persistence.xml 文件和web.xml中的persistence-unit-ref,以及定义的environment naming。我理解就是JNDI的name。

一般应用情景是:

在META-INF/persistence.xml中 使用<jta-data-source>java:/ MySqlDS</jta-data-source> 获取容器发布的Datesource。

transactions是使用的javaee容器支持的JTA系统,例如tomcat中,可以这样

如果你的项目准备部署在tomcat上,要支持jta,则需把相关的包放在tomcat/lib包下
1)jndi配置,可以把jndi的配置放置在 tomcat/conf/Catalina/域名(如localhost)/项目名.xml
文件的Context节点下,如下:
<Resource name="" auth="Container" type="javax.sql.DataSource"
username=""
password=""
driveClassName="oracle.jdbc.driver.OracleDriver"
url="" maxActive="45" maxIdle="25"/>
jndi也可以配置在server.xml,context.xml中
2)jta UserTransaction配置
在server.xml文件GlobalNamingResources节点下配置如下:
<!-- Resource configuration for UserTransaction
use JOTM -->
<Resource name="UserTransaction" auth="Container"
type="javax.transaction.UserTransaction"
factory="org.objectweb.jotm.UserTransactionFactory"
jotm.timeout="60"/>
然后在 项目名.xml 文件的context节点下加:
<ResourceLink name="UserTransaction"
global="UserTransaction"
type="javax.transaction.UserTransaction"/>

SPRING 仅仅做的是是把EntityManagerFactory通过依赖注入到应用的object中。如果要管理事务,则使用JtaTransactionManager。
3.LocalContainerEntityManagerFactoryBean
这个选项中,spring扮演了容器的角色。完全掌管JPA。

LocalContainerEntityManagerFactoryBean会根据persistence.xml创造一个PersistenceUnitInfo实现。

<beans>
<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="someDataSource"/>
<span style="color: #ff0000;"><property name="loadTimeWeaver">
</span><bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>
</beans>
不是所有的JPA provider都需要load-time weaving。hibernate就不需要。呵呵。 <property name="loadTimeWeaver">这个就不是必须的了。。

Persistence.xml配置:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="myUnit" transaction-type="RESOURCE_LOCAL">
<mapping-file>META-INF/orm.xml</mapping-file>
<exclude-unlisted-classes/>
</persistence-unit>
</persistence>
如何处理多个persistence units。spring提供了PersistenceUnitManager统一管理。

<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>org/springframework/orm/jpa/domain/persistence-multi.xml</value>
<value>classpath:/my/package/**/custom-persistence.xml</value>
<value>classpath*:META-INF/persistence.xml</value>
</list>
</property>
<span style="color: #ff0000;"><property name="dataSources"></span>
<map>
<entry key="localDataSource" value-ref="local-db"/>
<entry key="remoteDataSource" value-ref="remote-db"/>
</map>
</property>
<!-- if no datasource is specified, use this one -->
<property name="defaultDataSource" ref="remoteDataSource"/>
</bean>
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="pum"/>
<property name="persistenceUnitName" value="myCustomUnit"/>
</bean>
dataSources中的key是persistence.xml中配置的datasource名字,value-ref是spring管理的数据源。

另外:

EntityManagerFactory是线程安全的,但是EntityManager不是。

复制代码
public class ProductDaoImpl implements ProductDao {
private EntityManagerFactory emf;
@PersistenceUnit
public void setEntityManagerFactory(EntityManagerFactory emf) {
this.emf = emf;
}
public Collection loadProductsByCategory(String category) {
EntityManager em = this.emf.createEntityManager();
try {
Query query = em.createQuery("from Product as p where p.category = ?1");
query.setParameter(1, category);
return query.getResultList();
}
finally {
if (em != null) {
em.close();
}
}
}
}
复制代码
这样使用有个最大问题就是每次都要创建一个新的entityManager。那么该怎么办?

你可以通过@PersistenceContext获取一个transactional EntityManager("shared EntityManager")。为什么称它为transactional?因为它是一个共享的以及线程安全的当前的transactional EntityManager的一个代理。

复制代码
public class ProductDaoImpl implements ProductDao {
@PersistenceContext
private EntityManager em;
public Collection loadProductsByCategory(String category) {
Query query = em.createQuery("from Product as p where p.category = :category");
query.setParameter("category", category);
return query.getResultList();
}
}

时间: 2024-10-12 13:20:58

spring生成EntityManagerFactory的三种方式的相关文章

SSH深度历险(八) 剖析SSH核心原理+Spring依赖注入的三种方式

在java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中.依赖注入的另一种说法是"控制反转",通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做. Spring依赖注入(

Spring 使用AspectJ的三种方式

Spring 使用AspectJ 的三种方式 一,使用JavaConfig 二,使用注解隐式配置 三,使用XML 配置 背景知识: 注意 使用AspectJ 的 时候 要导入相应的Jar 包 嗯 昨天还碰到了这样的问题: Caused by: java.lang.IllegalArgumentEx http://pic.cnhubei.com/space.php?uid=1132&do=album&id=814854http://pic.cnhubei.com/space.php?uid=

Spring学习(二)spring ioc注入的三种方式

一.spring ioc注入有哪三种方式: a setter 原理 : 在目标对象中,定义需要注入的依赖对象对应的属性和setter方法:"让ioc容器调用该setter方法",将ioc容器实例化的依赖对象通过setter注入给目标对象,封装在目标对象的属性中. b 构造器 原理 : 为目标对象提供一个构造方法,在构造方法中添加一个依赖对象对应的参数.ioc容器解析时,实例化目标对象时会自动调用构造方法,ioc只需要为构造器中的参数进行赋值:将ioc实例化的依赖对象作为构造器的参数传入

【SSH三大框架】Spring基础第二篇:Spring依赖注入的三种方式

控制反转(Inversion of Control)和依赖注入(Dependency Injection): 应用控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它.也可以说,依赖被注入到对象中.所以,控制反转是,关于一个对象如何获取他所依赖的对象的引用,这个责任的反转. 对于依赖注入,有三种方式: 1.使用属性的setter方法注入 2.使用构造器注入 3.使用注解注入 下面我们介绍下这三种方式: 一.使用属性的setter方法注入 首先,我们写一个

PHP生成word的三种方式

摘要: 最近工作遇到关于生成word的问题 现在总结一下生成word的三种方法. btw:好像在博客园发表博客只要是标题带PHP的貌似点击量都不是很高(哥哥我标题还是带上PHP了),不知道为什么,估计博客园上net技术大牛比较多吧,如果把java,.net,php比作程序员的女友,那么java是Oracle门下的大家闺秀,.net微软旗下的名门望族,PHP则是草根门下的山村野姑,这让我等PHP草民闷骚男情何以堪情何以堪..牢骚发完了,正式写博客吧 正文 PHP生成word原理 利用windows

Web开发中获取Spring的ApplicationContext的三种方式

在 WEB 开发中,可能会很少需要显示的获得 ApplicationContext 来得到由 Spring 进行管理的某些 Bean, 今天我就遇到了,在这里和大家分享一下, WEB 开发中,怎么获取 ApplicationContext 一       要想怎么获取 ApplicationContext, 首先必须明白 Spring 内部 ApplicationContext 是怎样存储的.下面我们来跟踪一下源码 首先:从大家最熟悉的地方开始 Java代码   <listener> <

【Spring】创建对象的三种方式

关于Spring的搭建可参见:浅析Spring框架的搭建.在测试之前还是应该先将环境配置好,将相关Jar包导进来.Spring创建的对象,默认情况下都是单例模式,除非通过scope指定. 一.通过构造函数创建对象. 2.1 利用无参构造函数+setter方法注入值 最基本的对象创建方式,只需要有一个无参构造函数(类中没有写任何的构造函数,默认就是有一个构造函数,如果写了任何一个构造函数,默认的无参构造函数就不会自动创建哦!!)和字段的setter方法. Person类: package com.

Spring依赖注入的三种方式

Spring依赖注入(DI)的三种方式,分别为: 1. 接口注入 2. Setter方法注入 3. 构造方法注入 下面介绍一下这三种依赖注入在Spring中是怎么样实现的. 首先我们需要以下几个类: 接口 Logic.java 接口实现类 LogicImpl.java 一个处理类 LoginAction.java 还有一个测试类 TestMain.java Logic.java如下: package com.spring.test.di; public interface Logic { pub

spring mvc handler的三种方式

springmvc.xml 三种方式不能针对一个controller同时使用 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="