在Java应用中,存在多种数据访问API,如JDBC、JPA、JDO和Hibernate等。
为了便于使用这些数据访问API进行应用开发,Spring框架提供了Spring DAO,其带来的优势如下:
- 统一的应用接口
- 统一的异常层次结构DataAccessException
- 统一的资源标注@Repository
- 统一的事务管理@Transactional
下面以Hibernate为例,介绍Spring DAO与Hibernate的集成开发过程。
1.数据访问的基本过程
1)在XML配置文件中声明dataSource
可以是通用的Jakarta Commons DBCP数据源org.apache.commons.dbcp.BasicDataSource
<bean id="myDataSource" class="<strong>org.apache.commons.dbcp.BasicDataSource</strong>" destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
也可以是JNDI数据源<jee:jndi-lookup id="myDataSource" jndi-name="java:comp/env/jdbc/myds"/>
<beans>
<jee:jndi-lookup id="myDataSource" <strong>jndi-name</strong>="java:comp/env/jdbc/myds"/>
</beans>
2)在XML配置文件中声明sessionFactory
org.springframework.orm.hibernate5.LocalSessionFactoryBean
<bean id="mySessionFactory" class="<strong>org.springframework.orm.hibernate5.LocalSessionFactoryBean</strong>">
<property name="<strong>dataSource</strong>" ref="myDataSource"/>
<property name="mappingResources">
<list>
<value>product.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
</value>
</property>
</bean>
3)声明业务逻辑所需的DAO接口
4)Hibernate实现DAO接口,其中以Spring注入sessionFactory
public class ProductDaoImpl implements ProductDao {
private <strong>SessionFactory </strong>sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
<bean id="myProductDao" class="com.jdsu.nc.portal.ProductDaoImpl">
<property name="<strong>sessionFactory</strong>" ref="mySessionFactory"/>
</bean>
2.声明式事务管理的基本过程
1)在XML配置文件中声明dataSource(参考前文)
2)在XML配置文件中声明Hibernate的sessionFactory(参考前文)
3)在XML配置文件中声明Hibernate的transactionManager
<bean id="myTxManager"
class="<strong>org.springframework.orm.hibernate3.HibernateTransactionManager</strong>">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
4)在XML配置文件中声明具体的事务操作,并引用transactionManager
<tx:advice id="txAdvice" transaction-manager="myTxManager">
<tx:attributes>
<tx:method name="increasePrice*" propagation="REQUIRED"/>
<tx:method name="someOtherBusinessMethod" propagation="REQUIRES_NEW"/>
<tx:method name="*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
5)在XML配置文件中声明事务的插入点
<aop:config>
<aop:pointcut id="productServiceMethods"
expression="execution(* com.jdsu.nc.portal.ProductService.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/>
</aop:config>
上述设置,将对com.jdsu.nc.portal.ProductService接口的实现类中的方法加入到事务中执行。具体事务的属性,依据方法的名称(在tx:advice中定义)确定。
3.编程式事务管理的基本过程
编程式事务中的前3步骤与声明式事务一样,请参考前文。
区别在于,对Hibernate的transactionManager的引用不是在XML配置文件中定义,而是直接在服务实现的Java类中,示例如下:
public class ProductServiceImpl implements ProductService {
private <strong>TransactionTemplate </strong>transactionTemplate;
private <strong>ProductDao </strong>productDao;
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
public void setProductDao(ProductDao productDao) {
this.productDao = productDao;
}
...
}
Java类中引用的TransactionManager和ProductDao可以通过Spring注入:
<bean id="myProductService" class="com.jdsu.nc.portal.ProductServiceImpl">
<property name="transactionManager" ref="myTxManager"/>
<property name="productDao" ref="myProductDao"/>
</bean>