隨筆-42  評論-578  文章-1  trackbacks-0
                   此EntityDao接口與EntityDaoImpl實現類,可取代了我們平時寫的UserDao,NewsDao,CompanyDao等等,可直接供Service層調用.其中實現類的代碼如下:
          /**
           * Copyright 2009-1012 the original author or authors.
           * My Blog site: 
          http://www.aygfsteel.com/rongxh7
           
          */


          package rong.common.dao;
          import java.io.Serializable;
          import java.sql.SQLException;
          import java.util.List;
          import org.hibernate.Criteria;
          import org.hibernate.HibernateException;
          import org.hibernate.Query;
          import org.hibernate.Session;
          import org.hibernate.criterion.Criterion;
          import org.hibernate.criterion.Order;
          import org.hibernate.criterion.Restrictions;
          import org.springframework.orm.hibernate3.HibernateCallback;
          import org.springframework.stereotype.Repository;
          import rong.common.utils.Pager;
          import rong.util.MyHibernateDaoSupport;

          /**
           * Dao層接口的實現類
           * 許多人習慣根據不多的業務邏輯定義不同的DAO層接口,如UserDao,NewsDao,CompanyDao等等,
           * 這樣往往使得編碼量十分龐大,而且帶來了維護的困難,因此,抽取此DAO層接口,收錄大部分
           * DAO層必須的方法,以供Service層調用。
           * 
          @author rongxinhua
           * 
          @version 1.0
           * 
          @param <T> 范型,指實體類
           * 
          @param <PK> 范型,指實體類主鍵的數據類型,如Integer,Long
           * 
          @see rong.common.dao.EntityDao
           
          */


          @Repository(value
          ="entityDao")
          public class EntityDaoImpl<T,PK extends Serializable> extends MyHibernateDaoSupport implements EntityDao<T, PK>{

              
          /**
               * 保存實體
               * 包括添加和修改
               * 
          @param t 實體對象
               
          */

              
          public void saveOrUpdate(T t){
                  getHibernateTemplate().saveOrUpdate(t);
              }

              
              
          /**
               * 更新實體
               * 可用于添加、修改、刪除操作
               * 
          @param hql 更新的HQL語句
               * 
          @param params 參數,可有項目或多項目,代替Hql中的"?"號
               
          */

              
          public void update(final String hql,final Object params){
                  getHibernateTemplate().execute(
          new HibernateCallback(){

                      
          public Object doInHibernate(Session session)
                              
          throws HibernateException, SQLException {
                          Query query 
          = session.createQuery(hql);
                          
          for(int i=0; i<params.length; i++){
                              query.setParameter(i, params[i]);
                          }

                          query.executeUpdate();
                          
          return null;
                      }

                  }
          );
              }

              
              
          /**
               * 刪除實體
               * 
          @param t 實體對象
               
          */

              
          public void delete(T t){
                  getHibernateTemplate().delete(t);
              }

              
              
          /**
               * 刪除實體
               * 
          @param entityClass 實體類名
               * 
          @param id 實體的ID
               
          */

              
          public void delete(Class<T> entityClass,PK id){
                  getHibernateTemplate().delete(get(entityClass,id));
              }

              
              
          /**
               * 單查實體
               * 
          @param entityClass 實體類名
               * 
          @param id 實體的ID
               * 
          @return 實體對象
               
          */

              @SuppressWarnings(
          "unchecked")
              
          public T get(Class<T> entityClass,PK id){
                  
          return (T)getHibernateTemplate().get(entityClass, id);
              }

              
              
          /**
               * 查詢全部記錄列表
               * 
          @param entityClass 實體類名
               * 
          @param propertyName 排序的參照屬性
               * 
          @param isAsc 排序方式
               * 
          @param criterions 查詢條件,可為0項或任意多項目
               * 
          @return 記錄List集
               
          */

              
          public List<T> findAll(final Class<T> entityClass,final String propertyName,final boolean isAsc,final Criterion criterions){
                  
          int firstResult = 0;
                  
          int maxResults = 0;        //設置為0,則表示查詢全部記錄
                  return findByCriteria(entityClass, propertyName, isAsc, firstResult, maxResults, criterions);
              }

              
              
          /**
               * 查詢列表
               * 
          @param entityClass 實體類名
               * 
          @param propertyName 排序的參照屬性
               * 
          @param isAsc 排序方式,true表示升序,false表示降序,當propertyName賦值為null時,此參數無效
               * 
          @param firstResult 開始記錄序號
               * 
          @param maxResults 最大記錄數
               * 
          @param criterions 查詢條件,可有0項或任意多項目
               * 
          @return 記錄List集
               
          */

              @SuppressWarnings(
          "unchecked")
              
          public List<T> findByCriteria(final Class<T> entityClass,final String propertyName,final boolean isAsc,final int firstResult,final int maxResults,final Criterion criterions){
                  List
          <T> list = (List<T>)getHibernateTemplate().execute(new HibernateCallback(){

                      
          public Object doInHibernate(Session session)
                              
          throws HibernateException, SQLException {
                          Criteria criteria 
          = session.createCriteria(entityClass);
                          
          //按屬性條件查詢
                          for(Criterion criterion : criterions){
                              criteria.add(criterion);
                          }

                          
          //按某個屬性排序
                          if(null != propertyName){
                              
          if(isAsc){
                                  criteria.addOrder(Order.asc(propertyName));
                              }
          else{
                                  criteria.addOrder(Order.desc(propertyName));
                              }

                          }

                          
          //用于分頁查詢
                          if(maxResults != 0){
                              criteria.setFirstResult(firstResult);
                              criteria.setMaxResults(maxResults);
                          }

                          List
          <T> list = criteria.list();
                          
          return list;
                      }

                  }
          );
                  
          return list;
              }

              
              
          /**
               * 查詢總記錄數
               * 
          @param entityClass 實體類名
               * 
          @param criterions 查詢條件,可有0項或任意多項
               * 
          @return 總記錄數
               
          */

              
          public int findCountsByCriteria(final Class<T> entityClass,final Criterion criterions){
                      
          int totalCounts = (Integer)getHibernateTemplate().execute(new HibernateCallback(){

                      
          public Object doInHibernate(Session session)
                              
          throws HibernateException, SQLException {
                          Criteria criteria 
          = session.createCriteria(entityClass);
                          
          //按屬性條件查詢
                          for(Criterion criterion : criterions){
                              criteria.add(criterion);
                          }

                          
          int totalCounts = criteria.list().size();
                          
          return totalCounts;
                      }

                  }
          );
                  
          return totalCounts;
              }

              
              
              
          /**
               * 分頁查詢
               * 
          @param entityClass 實體類名
               * 
          @param propertyName 排序參照屬性
               * 
          @param isAsc 排序方式,true表示升序,false表示降序,當propertyName賦值為null時,此參數無效
               * 
          @param firstResult 開始記錄序號
               * 
          @param maxResults 最大記錄數
               * 
          @param criterions 查詢條件,可為0項或任意多項目
               * 
          @return 封裝List和totalCounts的Pager對象
               
          */

              @SuppressWarnings(
          "unchecked")
              
          public Pager<T> findForPager(final Class<T> entityClass,final String propertyName,final boolean isAsc,final int firstResult,final int maxResults,final Criterion criterions){
                  
          int totalCounts = findCountsByCriteria(entityClass, criterions);
                  List
          <T> entityList = findByCriteria(entityClass, propertyName, isAsc, firstResult, maxResults, criterions);
                  Pager pager 
          = new Pager();
                  pager.setTotalCounts(totalCounts);
                  pager.setEntityList(entityList);
                  
          return pager;
              }

              
              
          /**
               * 根據屬性值查詢列表
               * 
          @param entityClass 實體類名
               * 
          @param propertyName 屬性名
               * 
          @param value 屬性值
               * 
          @return List列表
               
          */

              
          public List<T> findByProperty(Class<T> entityClass,String propertyName,Object value){
                  Criterion criterion 
          = Restrictions.eq(propertyName, value);
                  List
          <T> list = findAll(entityClass, nulltrue, criterion);
                  
          return list;
              }

              
              
          /**
               * 根據屬性值查詢單個對象
               * 
          @param entityClass 實體類名
               * 
          @param propertyName 屬性名
               * 
          @param value 屬性值
               * 
          @return 實體對象
               
          */

              @SuppressWarnings(
          "unchecked")
              
          public T findUniqueByProperty(final Class<T> entityClass,final String propertyName,final Object value){
                  T t 
          = (T)getHibernateTemplate().execute(new HibernateCallback(){

                      
          public Object doInHibernate(Session session)
                              
          throws HibernateException, SQLException {
                          Criteria criteria 
          = session.createCriteria(entityClass).add(Restrictions.eq(propertyName, value));
                          T t 
          = (T)criteria.uniqueResult();
                          
          return t;
                      }

                  }
          );
                  
          return t;
              }

              
              
          /**
               * 根據屬性值查詢實體是否存在
               * 
          @param entityClass 實體類名
               * 
          @param propertyName 參照的屬性名
               * 
          @param value 屬性值
               * 
          @return 存在則返回true,不存在則返回false
               
          */

              
          public boolean isPropertyExist(final Class<T> entityClass,final String propertyName,final Object value){
                  
          boolean isExist = (Boolean)getHibernateTemplate().execute(new HibernateCallback(){

                      
          public Object doInHibernate(Session session)
                              
          throws HibernateException, SQLException {
                          Criteria criteria 
          = session.createCriteria(entityClass).add(Restrictions.eq(propertyName, value));
                          
          boolean isEmpty = criteria.list().isEmpty();
                          
          return ! isEmpty;
                      }

                  }
          );
                  
          return isExist;
              }

              
              
          /**
               * 
               * 
          @param hql 查詢語句
               * 用法如:可用于登錄驗證時,根據用戶名、密碼等信息查詢用戶
               * 
          @param params 參數數組,代替HQL中的"?"號,可有0項目或多項
               * 
          @return 唯一實體,返回null則表示不存在配置的實體
               * 
          @exception 如果查詢的結果集不唯一,則拋異常
               
          */

              @SuppressWarnings(
          "unchecked")
              
          public T findUniqueByHql(final String hql, final Object params ){
                  
                  T t 
          = (T)getHibernateTemplate().execute(new HibernateCallback(){

                      
          public Object doInHibernate(Session session)
                              
          throws HibernateException, SQLException {
                          Query query 
          = session.createQuery(hql);
                          
          for(int i=0; i<params.length; i++){
                              query.setParameter(i, params[i]);
                          }

                          T t 
          = (T)query.uniqueResult();
                          
          return t;
                      }

                  }
          );
                  
          return t;
              }

              
              
          /**
               * 按HQL條件查詢列表
               * 
          @param hql 查詢語句,支持連接查詢和多條件查詢
               * 
          @param params 參數數組,代替hql中的"?"號
               * 
          @return 結果集List
               
          */

              @SuppressWarnings(
          "unchecked")
              
          public List<T> findByHql(String hql,Object params){
                  List list 
          = getHibernateTemplate().find(hql, params);
                  
          return list;
              }

              
              
          /**
               * 按HQL分頁查詢
               * 
          @param firstResult 開始記錄號
               * 
          @param maxResults 最大記錄數
               * 
          @param hql 查詢語句,支持連接查詢和多條件查詢
               * 
          @param params 參數數組,代替餐hql中的"?"號
               * 
          @return 封裝List和total的Pager對象
               
          */

              @SuppressWarnings(
          "unchecked")
              
          public Pager<T> findForPagerByHql(final int firstResult, final int maxResults, final String hql, final Object params){
                  Pager
          <T> pager = (Pager<T>)getHibernateTemplate().execute(new HibernateCallback(){

                      
          public Object doInHibernate(Session session)
                              
          throws HibernateException, SQLException {
                          Query query 
          = session.createQuery(hql);
                          
          for(int position = 0; position < params.length; position ++){
                              query.setParameter(position, params[position]);
                          }

                          
          int totalCounts = query.list().size();    //總記錄數
                          
          //用于分頁查詢
                          if(maxResults > 0){
                              query.setFirstResult(firstResult);
                              query.setMaxResults(maxResults);
                          }

                          List
          <T> list = query.list();
                          Pager
          <T> pager = new Pager<T>();
                          pager.setEntityList(list);
                          pager.setTotalCounts(totalCounts);
                          
          return pager;
                      }

                  }
          );
                  
          return pager;
              }

              

          }


                相關說明:MyHibernateDaoSupport類是我自定義的類,該類繼承HibernateDaoSupport,相關代碼,請參考我的基于Annotation的Struts2.0+Hibernate3.3+Spring2.5整合開發 (2) ,EntityDao接口與實現類EntityDao的方法聲明一樣,在此暫且不貼出來.而代碼中用到的Pager類,是一個封裝list<Entity>和totalCounts的POJO類,代碼比較簡單,在此也不貼出來.
                開發本代碼之前,參考過以下資料:
          1)Springside的源碼
          2)一位北京網友發給我的項目中的代碼
                  (*^-^*) 本文原創,轉載請注明出處, http://www.aygfsteel.com/rongxh7謝謝! (*^-^*)

          本文原創,轉載請注明出處,謝謝!http://www.aygfsteel.com/rongxh7(心夢帆影JavaEE技術博客)
              

          posted on 2009-05-19 09:56 心夢帆影 閱讀(10469) 評論(20)  編輯  收藏 所屬分類: HibernateSpring

          評論:
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-05-19 10:55 | xx
          封裝的不錯,不知道會不會太細化了!  回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-05-19 12:36 | 幽夢新影
          不錯,值得一看~~  回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-05-19 16:36 | john locke
          不是新輪子吧。
          這種范型的dao類挺有用的  回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-05-20 17:20 | 無量字幕
          不錯  回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-05-20 20:55 | haidao
          博主你要就把所有相關的代碼都貼出來給新手學習嘛,哪有那樣缺一部分代碼,支支吾吾的,看著就冒火。這種東西javaeye上到處都是,何必搞得那樣神神秘秘  回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-05-21 00:31 | 心夢帆影
          @haidao
          1、從來沒有想過要搞你所謂的"神神秘秘,支支吾吾",只是省點篇幅而已;
          2、這些代碼,在Blogjava,Javaeye等網站上,當然有很多類似的,多了并不一定不好,有自己的特點就行,關鍵的是自己能靈活運用。
          3、只是看了一篇寫代碼的文章而已,你居然這么容易就冒火的?你可要仔細思考一下,你是不是真的適合搞這行。做Java程序員,學的東西多著呢,要看的文檔也多著呢,要寫的代碼更多著呢,你到時候可得整天冒火冒煙了。
          不過,還是感謝你的留言,貼代碼表示歉意。
          package rong.common.utils;
          import java.util.List;
          /**
          * 封裝分頁記錄的POJO類
          * @author rongxinhua
          *
          * @param <T> 范型,表示操縱的實體
          */
          public class Pager<T> {

          private List<T> entityList; //對象列表
          private int totalCounts; //總記錄數

          public List<T> getEntityList() {
          return entityList;
          }
          public void setEntityList(List<T> entityList) {
          this.entityList = entityList;
          }
          public int getTotalCounts() {
          return totalCounts;
          }
          public void setTotalCounts(int totalCounts) {
          this.totalCounts = totalCounts;
          }
          }  回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-06-02 10:26 | leilei


          有幸拜讀,受益頗多,多謝多謝。

          另有幾處疑問,麻煩幫忙指導一下啊。

          上述代碼中,有幾處用到final Criterion criterions的地方,例如

          public List<T> findAll(final Class<T> entityClass,final String propertyName,final boolean isAsc,final Criterion criterions){

          我是copy上面的代碼的,看到criterions前面有幾個省略號,不知道此處是否應該是final Criterion[] criterions ?這樣的地方有好幾處。

          另有一處地方:final Object params
          例如:public void update(final String hql,final Object params){
          其中的final Object params是否也應該為:final Object[] params ?
            回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-06-03 16:08 | javabeginer
          大俠,您好,我現在正在學習java,可否在您空閑的時候將這個項目的源代碼發給我,學習下,謝謝!dbemail@126.com  回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-06-04 00:26 | javabeginer
          您好,在使用eclipse實踐您的代碼時,比如用UserDao繼承EntityDao,UserDaoImpl繼承EntityDaoImpl實現UserDao時,有兩個方法需要重寫,他們分別是1、public void delete(Class entityClass, Object id) {} 2、public Object get(Class class1, Object id) {return null;},請問源代碼如何改進,使方法不再需要重寫。謝謝!!  回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現)[未登錄] 2009-06-12 16:31 | yuyu
          如果把final Criterion[] criterions寫成這樣 那下面的方法又有問題出現,
          public List<T> findByProperty(Class<T> entityClass,String propertyName,Object value){
          Criterion criterion = Restrictions.eq(propertyName, value);
          List<T> list = findAll(entityClass, null, true, criterion);
          return list;
          }

          這樣的話不能保持一致。 如果改啊?   回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-06-13 08:25 | metadmin
          看看我們這個怎么樣。 直接通過設計器打開數據庫表,然后通過鼠標定制出SQL,而且包括了系統的權限需求。
          FLASH演示:http://www.metadmin.com/download/showEmployees.html" target="_new" rel="nofollow">http://www.metadmin.com/download/showEmployees.html 演示了按照機構層級查詢員工的例子。

          ---------------------------------
          解開權限與業務耦合,提高開發效率
          細粒度權限管理軟件 試用版下載
          http://www.metadmin.com

            回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-06-25 14:28 | 黃燕青
          封裝的還不錯,我也想封裝。實現在DAO層里只有查詢的方法,那些插入、更新和刪除只在業務層調用工具類,但是還沒搞定。我看了你的這句話“此EntityDao接口與EntityDaoImpl實現類,可取代了我們平時寫的UserDao,NewsDao,CompanyDao等等,可直接供Service層調用”,你上面實現的不可以這樣做吧,我認為你的這個實現類可以當作DAO層的基類,比如public void update(final String hql,final Object params){},拼接HQL是在DAO層中進行的,我們一般都不會在業務層中拼接,不知道我說的對不對?  回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-06-25 14:32 | 黃燕青
          還有,我建議博主這個Object ...params(相當于Object[] params),改成Map<String, Object>,我感覺這樣可讀性高,因為參數是有參數名和值的  回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-06-25 18:00 | 心夢帆影
          @黃燕青
          可以直接供Service調用,不用再寫UserDao,NewsDao,CompanyDao等了.但正如你所說的,可能會在Service層寫HQL了,這樣,就增大了DAO層和Service層的偶合性了,這是不好的地方.  回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-06-25 18:04 | 心夢帆影
          @黃燕青
          寫成可變參數的形式,直接method(param1,param2,param3)插入值就行,如果,Map<String, Object>的話,可讀性強,但要通過構建Map實例,才能插入,即Map map = new HashMap();map.put("xxx","xxx"),再把它插入到method參數中method(map),兩者各有優點,也各有缺點,根據需要和個人所好使用.  回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-06-26 09:10 | 黃燕青
          @心夢帆影
          呵呵,說的有道理,java學的東西真多,哎,感覺自己學的很少。
            回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-07-29 11:53 | chumq
          final Criterion criterions 如何給它傳值呢?不是很清楚。謝謝回答  回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2009-10-29 17:18 | 379548695
          是啊老大你這個final Criterion criterions
          再業務層是怎么創建的啊?  回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現)[未登錄] 2010-07-25 18:51 | 過客
          不錯 很好的示例 謝了  回復  更多評論
            
          # re: 奮斗兩天,終于開發了自己的DAO層公共類(Spring+Hibernate實現) 2013-07-08 19:22 | www
          findForPagerByHql方法中用 int totalCounts = query.list().size();獲取總記錄數,query.list()相當于是先查出所有的對象,如果數據量大,已經內存溢出了  回復  更多評論
            
          主站蜘蛛池模板: 嘉定区| 贺兰县| 金塔县| 格尔木市| 阿图什市| 韶山市| 咸宁市| 微山县| 衡阳县| 临高县| 西畴县| 岑溪市| 松原市| 巧家县| 星座| 浮山县| 准格尔旗| 兴化市| 辽宁省| 和平县| 西平县| 遂昌县| 西盟| 芦山县| 武乡县| 麻栗坡县| 莱西市| 芒康县| 正镶白旗| 石棉县| 闸北区| 綦江县| 泗洪县| 盐城市| 丽江市| 甘泉县| 托里县| 西乌珠穆沁旗| 图片| 磴口县| 潞城市|