Spring Framework最得以出名的是与Hibernate的无缝链接,基本上用Spring,就会用Hibernate。可惜的是Spring提供的HibernateTemplate功能显得不够,使用起来也不是很方便。我们编程序时,一般先写BusinessService,由BusinessService调DAO来执行存储,在这方面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,快速实现业务逻辑。
具体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>
|