1.配置数据源
Spring提供了在Spring上下文中配置数据源Bean的多种方式,包括:
通过JDBC驱动程序定义的数据源
通过JNDI查找的数据源
连接池的数据源
1.1使用JNDI数据源
Spring通常部署在应用服务器中,这些服务器允许配置通过JNDI获取数据源。这种配置的好处在于数据源完全可以在应用程序
之外进行管理。
利用Spring我们可以像使用Spring Bean那样配置JNDI中数据源的引用并将其装配到需要的类中。位于jee命名空间下<jee:jndi-lookup>元素可以用于检索
JNDI中的任何对象,并将其用在Spring Bean中
<jee:jndi-lookup id="dataSource" jndi-name="/jdbc/MyDS" resource-ref="true" />
其中jndi-name属性用于指定JDNI中资源的名称。如果只设置了jndi-name属性,那么就会根据指定的名称查找数据源。
但是,如果应用程序运行在java应用程序服务器中,则需要将resouce-ref属性设置为true,这样给定的jndi-name将会自动添加
java:comp/env/前缀。
1.2使用数据源连接池
如果你不能从JNDI中查找数据源,那么下一个选择就是直接在Spring中配置数据源连接池。
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:hsql://localhost/mydb" />
<property name="username" value="sa" />
<property name="password" value="sa" />
<property name="initialSize" value="5" />
<property name="maxActive" value="10" />
</bean>
1.3基于JDBC驱动的数据源
。。。
2.在Spring中集成Hibernate
复杂特性:
*延迟加载(Lazy loading):随着对象关系变得越来越复杂,有时候我们并不希望立即获取完成的对象间关系。
*优先抓取(Eager fetching): 这雨延迟加载是相对的。借助于优先抓取,我们可以使用一个查询获取完整的关联对象。
*级联(Cascading):有时,更该数据库中的表会同时修改其他表。
一些可用的框架提供了这样的服务,这些服务的通用名称是对象/关系映射(ORM)
Spring对ORM框架的支持提供了与这些框架的集成点以及一些附加的服务。如下所示
*Spring 声明式事务的集成支持
*透明的异常处理
*线程安全的、轻量级的模版类
* DAO支持类
*资源管理
2.1声明Hibernate的Session Factory
Session接口提供了基本的数据访问功能,通过Hibernate的Session接口 应用程序的Dao能满足所有的持久化需求
获取Hibernate Session对象的标准方式是借助与Hibernate的SessionFactory接口的实现类。除了一些其他的任务,SessionFactory主要负责
Hibernate Session的打开、关闭与管理.
在Spring中 我们要通过Spring的某一个Hibernate Session工厂Bean来获取Hibernate的SessionFactory.我们可以在应用程序的上下文中,像配置
其他Bean那样来配置Hibernate Session工厂。
如果选择在XML中定义对象与数据库之间的映射,那么需要在Spring中配置LocalSessionFactoryBean
如果选择使用注解的方式来定义持久化,那需要使用AnnotationSessionFactoryBean来替代LocalSessionFactoryBean
2.3构造不依赖于Spring的Hibernate代码
使用@Autowired注解可以让Spring自动将一个SessionFactory注入到HibernateSpitterDao的sessionFactory属性中。
接下来哉currentSession()方法中,使用这个SessionFactory来获取当前事务的Session
另外还需要注意的是,我们在类上使用了@Repository注解,这会为我们做两件事情。首先@Repository是Spring的另一种构造注解,它能像其他注解一样被
spring的<context:component-scan>所扫描到,这样就不必明确声明HibernateSpitterDao bean了。
除了简化xml配置外 @Repository还有另外一个用处异常转化处理 需要在应用上下文中添加 PersistenceExceptionTranslationPostProcessor bean.
2.4 spring与jpa
Spring 中使用JPA的第一步是要在Spring 应用上下文中将实体管理器工厂
2.4.1配置实体管理器工厂
简单来说,基于JPA的应用程序使用EntityManagerFactory的实现类来获取EntityManager实例,jpa定义了两种类型的实体管理器
以上两种实体管理器实现了同一个EntityManager接口,关键的区别不在于EntityManager本身,而是在于EntityManager的创建和
管理方式,应用程序管理类型的EntityManager是由EntityManagerFactory创建的。EntityManagerFactory是通过PersistenceProvider的createEntityManagerFactory()方法得到的
容器管理的EntityManagerFactory是通过PersistenceProvider的createContainerEntityManagerFactory()方法获得的。
2.4.2 使用应用程序管理类型的JPA
对于应用程序管理类型的实体管理器工厂来说,他对大部分配置文件来源于一个名为persistence.xml的配置文件,这个文件必须位于类路径下的META-INF目录下
persistence.xml的作用在于定一个或多个持久化单元。持久化单元是同一个数据源下的一个或多个持久化类。
因为在persistence.xml文件中包含了大量的配置信息,所以在Spring中需要配置的就很少了。可以通过以下<bean>元素在Spring中声明LocalEntityManagerFactoryBean
赋给persistenceUnitName属性的值就是persistence.xml中持久化单元的名称
*创建应用程序管理类型的EntityManagerFactory都是在persistence.xml中进行的。而正是应用程序管理的本意。在应用程序管理的场景下
完全由应用程序本身来负责获取EntityManagerFactory,这是通过JPA实现的PersistenceProvider做到的。如果每次请求EntityManagerFactory时都要定义持久化单元。
代码将会迅速膨胀。通过将其配置在persistence.xml中,JPA就能在这个特定的位置查找持久化单元定义了。
但借助于Spring对JPA的支持。我们不再需要直接处理PersistenceProvider了。因此,再将配置信息放在persistence.xml中就显得不那么明智了,实际上这样阻止了我们在Spring中配置EntityManagerFactory(如果不是这样,则可以提供一个Spring配置的数据源)
*使用容器管理类型的JPA
容器管理的JPA采取了一种不同的方式。当容器在运行时,可以使用容器(在我们的场景下是Spring)提供的信息来生成EntityManagerFactory.
可以将数据源信息配置在Spring应用上下文中,而不是在persistence.xml中了。例如,如下的<bean>声明展现了在Spring中如何使用LocalContainerEntiryManagerFactoryBean
来配置容器管理类型的JPA
这里我们使用Spring 配置的数据源来设置dataSource属性。任何javax.sql.DataSource的实现都可以。尽管数据源还可以在persistence.xml进行配置,但这个属性的数据源具有更高的优先级。
jpaVendorAdapter属性用于指明所使用的是哪一个厂商的JPA实现。Spring提供了多个JPA厂商适配器
最有用的属性是database属性,设置数据库的类型
3.编写JPA的DAO
Spring对JPA集成提供了JpaTemplate模版以及对应的支持类JpaDaoSupport.但是为了实现更纯粹的JPA方式,基于模版的JPA已经被弃用。
不使用Spring的JPA DAO
jpaSpitterDao使用了EntityManager处理持久化。通过EntityManager Dao非常干净并且看起来就像没有使用Spring的DAO,但是它从哪里得到的EntityManager呢?
需要注意的是em属性上使用了@PersistentContext注解。简单来讲这个注解表明需要将一个EntityManger实例注入到em上。为了在Spring中实现EntityManager注入。
我们需要在Spring应用上下文中配置一个PersistenceAnnotationBeanPostProcessor
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
@Repository注解,它的作用与开发Hibernate上下文Session版本的DAO时是一致的。由于没有模版类来处理异常,所以我们需要为DAO添加@Repository注解
这样PersistenceExceptionTranslationPostProcessor就会知道要将这个Bean产生的异常转换成Spring的统一数据访问异常。
@Transactional表明这个DAO中的持久化方法是在事务上下文中执行的。
不管是JPA还是Hibernate,异常转换都不是强制要求的。省略PersistenceExceptionTranslationPostProcessor,原来的异常就会正常的处理。