Spring Framework最得以出名的是與Hibernate的無縫鏈接,基本上用Spring,就會用Hibernate??上У氖荢pring提供的HibernateTemplate功能顯得不夠,使用起來也不是很方便。我們編程序時,一般先寫B(tài)usinessService,由BusinessService調DAO來執(zhí)行存儲,在這方面Spring沒有很好的例子,造成真正想用好它,并不容易。
我們的思路是先寫一個BaseDao,仿照HibernateTemplate,將基本功能全部實現:
public class BaseDao extends HibernateDaoSupport{
private Log log = LogFactory.getLog(getClass());
public Session openSession() {
return SessionFactoryUtils.getSession(getSessionFactory(), false);
}
public Object get(Class entityClass, Serializable id) throws DataAccessException {
Session session = openSession();
try {
return session.get(entityClass, id);
}
catch (HibernateException ex) {
throw SessionFactoryUtils.convertHibernateAccessException(ex);
}
}
public Serializable create(Object entity) throws DataAccessException {
Session session = openSession();
try {
return session.save(entity);
}
catch (HibernateException ex) {
throw SessionFactoryUtils.convertHibernateAccessException(ex);
}
}
...
其它的DAO,從BaseDao繼承出來,這樣寫其他的DAO,代碼就會很少。
從BaseDao繼承出來EntityDao,專門負責一般實體的基本操作,會更方便。
public interface EntityDao {
public Object get(Class entityClass, Serializable id) throws DataAccessException;
public Object load(Class entityClass, Serializable id) throws DataAccessException;
public Serializable create(Object entity) throws DataAccessException;
...}
/**
* Base class for Hibernate DAOs. This class defines common CRUD methods for
* child classes to inherit. User Sping AOP Inteceptor
*/
public class EntityDaoImpl extends BaseDao implements EntityDao{
}
為了Transaction的控制,采用AOP的方式:
public interface EntityManager {
public Object get(Class entityClass, Serializable id);
public Object load(Class entityClass, Serializable id);
public Serializable create(Object entity);
...
}
/**
* Base class for Entity Service. User Sping AOP Inteceptor
*/
public class EntityManagerImpl implements EntityManager {
private EntityDao entityDao;
public void setEntityDao(EntityDao entityDao) {
this.entityDao = entityDao;
}
public Object get(Class entityClass, Serializable id) {
return entityDao.get(entityClass, id);
}
public Object load(Class entityClass, Serializable id) {
return entityDao.load(entityClass, id);
}
...
}
這樣我們就有了一個通用的Hibernate實體引擎,可以對任何Hibernate實體實現基本的增加、修改、刪除、查詢等。
其它的BusinessService就可以繼承EntityManager,快速實現業(yè)務邏輯。
具體XML配置如下:
<!-- Oracle JNDI DataSource for J2EE environments -->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>java:comp/env/jdbc/testPool</value></property>
</bean>
<!-- Hibernate SessionFactory for Oracle -->
<!-- Choose the dialect that matches your "dataSource" definition -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<value>user-hbm.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.Provider</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<!-- AOP DAO Intecepter -->
<bean id="hibernateInterceptor" class="org.springframework.orm.hibernate.HibernateInterceptor">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="entityDaoTarget" class="com.gpower.services.entity.dao.EntityDaoImpl">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="entityDao" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.gpower.services.entity.dao.EntityDao</value>
</property>
<property name="interceptorNames">
<list>
<value>hibernateInterceptor</value>
<value>entityDaoTarget</value>
</list>
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<!-- Transaction manager that delegates to JTA (for a transactional JNDI DataSource) -->
<!--
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
-->
<!-- Transactional proxy for the Application primary business object -->
<bean id="entityManagerTarget" class="com.gpower.services.entity.EntityManagerImpl">
<property name="entityDao">
<ref bean="entityDao"/>
</property>
</bean>
<bean id="entityManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="target">
<ref bean="entityManagerTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_SUPPORTS</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>