`
sun_cat
  • 浏览: 72617 次
社区版块
存档分类
最新评论

一个DAO 一个Interface 搞定spring + hibernate+动态hql查询

阅读更多

找了一些spring的文章看了下,有所启发,于是大概的总结了下,希望大家多提提意见

为了实现自己程序对spring和hibernate的过分依赖,因此自己写了一个接口,封装了8个常用的数据库操作

接口如下

java 代码
  1. package com.pig.dao;   
  2.   
  3. import java.io.Serializable;   
  4. import java.util.Collection;   
  5. import java.util.List;   
  6.   
  7. import org.springframework.dao.DataAccessException;   
  8.   
  9. /**  
  10.  * 实现具体数据访问的接口,该接口将程序和框架进行了分离,提供了抽象出来的几个常用的方法 优点:减少了对spring,hibernate的依赖  
  11.  * 缺点:提供了有限的几个方法,可能造成提供的方法不全  
  12.  *   
  13.  * @author lizhihui  
  14.  * @see DAOInterfaceHibernate3Imp  
  15.  */  
  16.   
  17. public interface DAOInterface {   
  18.   
  19.     /**  
  20.      * Persist the given transient instance.  
  21.      * @param entity the transient instance to persist  
  22.      * @return the generated identifier  
  23.      */  
  24.     public Serializable save(Object entity);   
  25.   
  26.     /**  
  27.      * Save or update the given persistent instance,  
  28.      * according to its id (matching the configured "unsaved-value"?).  
  29.      * @param entity the persistent instance to save or update  
  30.      * (to be associated with the Hibernate Session)  
  31.      * @throws DataAccessException in case of Hibernate errors  
  32.      * @see net.sf.hibernate.Session#saveOrUpdate(Object)  
  33.      */  
  34.     public void saveOrUpdate(Object entity) throws DataAccessException;   
  35.   
  36.     /**  
  37.      * Save or update all given persistent instances,  
  38.      * according to its id (matching the configured "unsaved-value"?).  
  39.      * @param entities the persistent instances to save or update  
  40.      * (to be associated with the Hibernate Session)  
  41.      * @throws DataAccessException in case of Hibernate errors  
  42.      * @see net.sf.hibernate.Session#saveOrUpdate(Object)  
  43.      */  
  44.     public void saveOrUpdate(Collection entities) throws DataAccessException;   
  45.   
  46.     /**  
  47.      * Delete the given persistent instance.  
  48.      * @param entity the persistent instance to delete  
  49.      * @throws org.springframework.dao.DataAccessException in case of Hibernate errors  
  50.      * @see net.sf.hibernate.Session#delete(Object)  
  51.      */  
  52.     public void delete(Object entity) throws DataAccessException;   
  53.   
  54.     /**  
  55.      * Delete the instance according to identifier  
  56.      * @param c class of instance  
  57.      * @param id identifier   
  58.      * @throws org.springframework.dao.DataAccessException in case of Hibernate errors  
  59.      */  
  60.     public void delete(Class c, Serializable id) throws DataAccessException;   
  61.   
  62.     /**  
  63.      * Delete all given persistent instances.  
  64.      * 

    This can be combined with any of the find methods to delete by query

     
  65.      * in two lines of code, similar to Session's delete by query methods.  
  66.      * @param entities the persistent instances to delete  
  67.      * @throws org.springframework.dao.DataAccessException in case of Hibernate errors  
  68.      * @see net.sf.hibernate.Session#delete(String)  
  69.      */  
  70.     public void delete(Collection entities) throws DataAccessException;   
  71.   
  72.     /**  
  73.      * Return the persistent instance of the given entity class  
  74.      * with the given identifier, throwing an exception if not found.  
  75.      * 

    This method is a thin wrapper around

     
  76.      * {@link net.sf.hibernate.Session#load(Class, java.io.Serializable)} for convenience.  
  77.      * For an explanation of the exact semantics of this method, please do refer to  
  78.      * the Hibernate API documentation in the first instance.  
  79.      * @param entityClass a persistent class  
  80.      * @param id an identifier of the persistent instance  
  81.      * @return the persistent instance  
  82.      * @throws org.springframework.orm.ObjectRetrievalFailureException if not found  
  83.      * @throws org.springframework.dao.DataAccessException in case of Hibernate errors  
  84.      * @see net.sf.hibernate.Session#load(Class, java.io.Serializable)  
  85.      */  
  86.     public Object load(Class entityClass, Serializable id) throws DataAccessException;   
  87.        
  88.     /**  
  89.      * Execute an HQL query  
  90.      * @param queryString a query expressed in Hibernate's query language  
  91.      * @return a List containing the results of the query execution  
  92.      * @throws org.springframework.dao.DataAccessException in case of Hibernate errors  
  93.      * @see net.sf.hibernate.Session#find(String, Object[], net.sf.hibernate.type.Type[])  
  94.      * @see net.sf.hibernate.Session#createQuery  
  95.      */  
  96.     public List find(String queryString) throws DataAccessException;   
  97.        
  98. }   

 

他的实现

java 代码
  1. package com.pig.dao;   
  2.   
  3. import java.io.Serializable;   
  4. import java.sql.SQLException;   
  5. import java.util.Collection;   
  6. import java.util.List;   
  7.   
  8. import org.apache.commons.logging.Log;   
  9. import org.apache.commons.logging.LogFactory;   
  10. import org.hibernate.HibernateException;   
  11. import org.hibernate.Query;   
  12. import org.hibernate.Session;   
  13. import org.springframework.dao.DataAccessException;   
  14. import org.springframework.orm.hibernate3.HibernateCallback;   
  15. import org.springframework.orm.hibernate3.support.HibernateDaoSupport;   
  16.   
  17. public class DAOInterfaceHibernate3Imp extends HibernateDaoSupport implements DAOInterface {   
  18.   
  19.     private static Log log=LogFactory.getLog(DAOInterfaceHibernate3Imp.class);   
  20.        
  21.     public void delete(Object entity) throws DataAccessException {   
  22.         getHibernateTemplate().delete(entity);   
  23.     }   
  24.   
  25.     public void delete(Class c, Serializable id) throws DataAccessException {   
  26.         Object entiry = load(c, id);   
  27.         getHibernateTemplate().delete(entiry);   
  28.     }   
  29.   
  30.     public void delete(Collection entities) throws DataAccessException {   
  31.         getHibernateTemplate().deleteAll(entities);   
  32.     }   
  33.   
  34.     public List find(String queryString) throws DataAccessException {   
  35.         return getHibernateTemplate().find(queryString);   
  36.     }   
  37.   
  38.     public Object load(Class entityClass, Serializable id) throws DataAccessException {   
  39.         return getHibernateTemplate().load(entityClass, id);   
  40.     }   
  41.   
  42.     public Serializable save(Object entity) {   
  43.         return getHibernateTemplate().save(entity);   
  44.     }   
  45.   
  46.     public void saveOrUpdate(Object entity) throws DataAccessException {   
  47.         getHibernateTemplate().saveOrUpdate(entity);   
  48.     }   
  49.   
  50.     public void saveOrUpdate(Collection entities) throws DataAccessException {   
  51.         getHibernateTemplate().saveOrUpdateAll(entities);   
  52.     }   
  53.   
  54.   
  55. }   

 

这样如果 hibernate如果有了变得 只改变他的实现类就可以了,甚至可以改变成其他的中间件实现

 在程序中只用了实现了一个DAO,感觉他可以对所以的类操作了,至于其他的和业务相关联的操作 例如用户登陆,修改秘密等操作 我把他们归结到了 service中,这样service的实现可能要好多的类和接口

大家看下我的DAO

java 代码
  1. package com.pig.dao;   
  2.   
  3. import java.io.Serializable;   
  4. import java.util.Collection;   
  5. import java.util.List;   
  6.   
  7. import org.springframework.dao.DataAccessException;   
  8.   
  9. import com.pig.util.PropertyResource;   
  10.   
  11.   
  12. public class BasicDAO {   
  13.        
  14.     private DAOInterface dao;   
  15.     private PropertyResource sqlMapping;   
  16.        
  17.     public BasicDAO(){   
  18.            
  19.     }   
  20.        
  21.     public void delete(Object entity) throws DataAccessException {   
  22.         dao.delete(entity);   
  23.     }   
  24.   
  25.     public void delete(Class c, Serializable id) throws DataAccessException {   
  26.         dao.delete(c,id);   
  27.     }   
  28.   
  29.     public void delete(Collection entities) throws DataAccessException {   
  30.         dao.delete(entities);   
  31.     }   
  32.   
  33.     public List find(String queryStringKey,Object[] args) throws DataAccessException {   
  34.         return dao.find(sqlMapping.getFormattedString(queryStringKey, args));   
  35.     }   
  36.   
  37.     public Object load(Class entityClass, Serializable id) throws DataAccessException {   
  38.         return dao.load(entityClass, id);   
  39.     }   
  40.   
  41.     public Serializable save(Object entity) {   
  42.         return dao.save(entity);   
  43.     }   
  44.   
  45.     public void saveOrUpdate(Object entity) throws DataAccessException {   
  46.         dao.saveOrUpdate(entity);   
  47.     }   
  48.   
  49.     public void saveOrUpdate(Collection entities) throws DataAccessException {   
  50.         dao.saveOrUpdate(entities);   
  51.     }   
  52.   
  53.        
  54. }   

在这个DAO中注入了一个DAOInterface 和 一个properties 文件 这个文件可以根据key来找到对应的hql 或者sql语句 并将参数格式化进去,看下这个方法

java 代码
  1. public List find(String queryStringKey,Object[] args) throws DataAccessException {   
  2.     return dao.find(sqlMapping.getFormattedString(queryStringKey, args));   
  3. }  

这个方法直接根据给定的hql语句 查询出结果集。本来还想给出一个根据hql来更新数据库的操作,但是发现hibernate好像没有提供这个接口(我对hibernate的了解还不是很多)

下面将读取hql文件的的类也一并给出 大家参考下把,这个hql文件应该放到classpath下

java 代码
  1. package com.pig.util;   
  2.   
  3. import java.text.MessageFormat;   
  4. import java.util.*;   
  5.   
  6. /**  
  7.  * read properties file in classpath  
  8.  * @author lzh  
  9.  * @version 1.0  
  10.  */  
  11.   
  12. public class PropertyResource {   
  13.   
  14.     private String resourceName;   
  15.   
  16.     private Locale locale;   
  17.   
  18.     private Map<String, String> properties;   
  19.   
  20.     public PropertyResource() {   
  21.     }   
  22.   
  23.     private void init() {   
  24.         if (properties == null) {   
  25.             properties = new Hashtable<String, String>();   
  26.             ResourceBundle rb = null;   
  27.             if (locale == null) {   
  28.                 rb = ResourceBundle.getBundle(resourceName);   
  29.             } else {   
  30.                 rb = ResourceBundle.getBundle(resourceName, locale);   
  31.             }   
  32.             Enumeration<String> e = rb.getKeys();   
  33.             String key = null;   
  34.             String value = null;   
  35.             while (e.hasMoreElements()) {   
  36.                 key = e.nextElement();   
  37.                 value = rb.getString(key);   
  38.                 properties.put(key, value);   
  39.             }   
  40.         }   
  41.     }   
  42.   
  43.     public String getString(String key) {   
  44.         if (properties == null) {   
  45.             init();   
  46.         }   
  47.         return properties.get(key);   
  48.     }   
  49.   
  50.     public String getString(String key, String defaultValue) {   
  51.         if (properties == null) {   
  52.             init();   
  53.         }   
  54.         String value = properties.get(key);   
  55.         return value == null ? defaultValue : value;   
  56.     }   
  57.   
  58.     public String getFormattedString(String key, Object args[]) {   
  59.         String msg = MessageFormat.format(getString(key), args);   
  60.         return msg;   
  61.     }   
  62.   
  63.     public Locale getLocale() {   
  64.         return locale;   
  65.     }   
  66.   
  67.     public void setLocale(Locale locale) {   
  68.         this.locale = locale;   
  69.     }   
  70.   
  71.     public String getResourceName() {   
  72.         return resourceName;   
  73.     }   
  74.   
  75.     public void setResourceName(String resourceName) {   
  76.         this.resourceName = resourceName;   
  77.     }   
  78. }   

 

最后大家看下我spring的配置文件把,这个配置文件还配置了对事务的管理(参考了他人的做法)

java 代码
  1. <!-- Hibernate SessionFactory -->   
  2. <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">   
  3.     <property name="dataSource" ref="dataSource"/>   
  4.     <property name="mappingResources">   
  5.         <list>   
  6.         </list>   
  7.     </property>   
  8.     <property name="hibernateProperties">   
  9.         <props>   
  10.             <prop key="hibernate.dialect">${hibernate.dialect}</prop>   
  11.             <prop key="hibernate.show_sql">true</prop>   
  12.             <prop key="hibernate.generate_statistics">true</prop>   
  13.         </props>   
  14.     </property>   
  15.     <property name="eventListeners">   
  16.         <map>   
  17.             <entry key="merge">   
  18.                 <bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>   
  19.             </entry>   
  20.         </map>   
  21.     </property>   
  22. </bean>   
  23.   
  24. <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->   
  25. <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">   
  26.     <property name="sessionFactory" ref="sessionFactory"/>   
  27. </bean>   
  28.   
  29. <!--define bean of transaction interceptor -->     
  30.    <bean id="transactionInterceptor"  class="org.springframework.transaction.interceptor.TransactionInterceptor">     
  31.        <property name="transactionManager" ref="transactionManager" />     
  32.        <property name="transactionAttributes">     
  33.            <props>     
  34.                <prop key="insert*">PROPAGATION_REQUIRED</prop>     
  35.                <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>     
  36.                <prop key="*">PROPAGATION_REQUIRED</prop>     
  37.            </props>     
  38.        </property>     
  39.    </bean>     
  40.     
  41.    <!-- define BeanNameAutoProxyCreator-->     
  42.    <bean  class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">     
  43.        <property name="beanNames">     
  44.        <!-- 所有名字以DAO,Service结尾的bean,将由该"bean后处理器"为其创建事务代理;实际上应该在业务层进行事务管理,这里只是举一个简单例子 -->     
  45.            <value>*DAO,*Service</value>     
  46.        </property>     
  47.        <!--  下面定义BeanNameAutoProxyCreator所需的事务拦截器-->     
  48.        <property name="interceptorNames">     
  49.            <list>     
  50.                <!-- 可以增加其他的拦截器 -->     
  51.                <value>transactionInterceptor</value>     
  52.            </list>     
  53.        </property>     
  54.    </bean>     
  55.   
  56.   
  57. <!-- ========================= BUSINESS OBJECT DEFINITIONS ========================= -->   
  58. <bean id="daoInterface" class="com.pig.dao.DAOInterfaceHibernate3Imp">   
  59.     <property name="sessionFactory" ref="sessionFactory"/>   
  60. </bean>   
  61.   
  62. <bean id="sqlPropertyResource" class="com.pig.util.PropertyResource">   
  63.     <property name="resourceName" value="com.pig.resource"/>   
  64. </bean>   
  65.        
  66. <bean id="basicDAO" class="com.pig.dao.BasicDAO">   
  67.     <property name="dao" ref="daoInterface"/>   
  68.     <property name="sqlMapping" ref="sqlPropertyResource"/>   
  69. </bean>   

 

希望大家能多提意见,偶对spring才看了没几天,看了大家的贴子,可以说是照葫芦画瓢  见笑见笑

分享到:
评论
6 楼 sun_cat 2007-03-15  
昨天晚上本来打算上传附件的 可是老是上传不上去
偶是刚开始学spring 希望大家多多指教
5 楼 eyejava 2007-03-15  
BasicDAO 包装DAOInterface 还真有点怪怪的,只是多了一个find方法而已.
另外hql 放在配置文件里面运行期间的参数接收将很麻烦.
appgen 已经提供生成dao代码的模版, 这些重复的代码都可以不用手工写的.
4 楼 jfy3d 2007-03-15  
我也这么用 不过是Ibatis的
因为SQL在SQLMAP 里 功能应该比ResourceBundle更多些
连service也简化了

普通GRUD的service
只要
public UserService extends BaseService {
}
就可以了

单DAO 确实提高很大生产速度
3 楼 daoger 2007-03-15  
这是常用的配置方式中的一种,希望LZ进一步研究,能有更好的文章分享!
2 楼 huangpengxiao 2007-03-15  
严重同意楼上
1 楼 lighter 2007-03-14  
1、建议楼主打包一下程序,方便看一下,这样拉下来,看得头昏
2、“搞定spring + hibernate+动态hql查询”有标题党的嫌疑,有时间看清楚后再回复你的帖子

相关推荐

Global site tag (gtag.js) - Google Analytics