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>
|