Hibernate反射DAO模式

在持久層框架中,若是咱們要像簡單的JDBC鏈接數據庫那樣寫一個通用的Dao方法的話,那麼把JDBC簡單的業務邏輯搬到hibernate持久層框架中,固然是不可能的,這裏主要的問題就在於hibernate持久層框架中,由於它不是像JDBC那樣簡單的增刪改查的編寫,而是要針對實體類映射配置文件來對照數據庫表字段進行操做,並且操做是面向對象的查詢,不是簡單的sql語句的查詢,這樣咱們的通用DAO模式就不能是簡單的JDBC思路了。 java

試想,項目底層的通用DAO接口方法,是適用於全部實體類對象應用的,並且數據庫讀取的全部實體類集合也是一個通用的類模型。這樣,和簡單的JDBC模式不一樣的基礎上,hibernate通用的DAO模型,就須要咱們利用反射序列化的技術機制來完成。所以不管是插入的類對象和讀取的類模型信息,經過反射序列化來獲取。具體的操做流程以下: sql

首先,在咱們的通用DAO接口中,體現出全部通用功能的方法名外,咱們須要定義的另一個技術,就是泛型類編程模式,咱們須要給類加上類型,也就是給類加上泛型模式編程。另外,在泛型中,須要定義兩個屬性,1是給類加一個繼承序列化的變量,和給主鍵ID繼承的一個序列化。所以反射DAO接口以下: 數據庫

public interface
IGenericDao<T
extends Serializable,ID extends Serializable> 編程

另外,全部的功能方法名,隨之也會有所更改,例如咱們添加一條信息時候,以前的參數是須要具體的實體類對象,而如今則是泛型的屬性爲實體類的對象,以下: session

public T create(T entity);返回值也是同樣。 框架

所以在通用DAO接口如圖: ide

具體的類實現中,除了實現該通用的DAO接口外,還須要自身的泛型編程和繼承HibernateDaoSupport父類,所以實現類的方法名爲: this

public class
GenericHibernateDao<T
extends
Serializable,ID
extends Serializable> extends HibernateDaoSupport  implements
IGenericDao<T, ID>
spa

所以例如在插入數據時候實現類代碼則是: hibernate

@Override

    public T create(T entity) {

       return (T) this.getHibernateTemplate().save(entity);

    }

這裏反射序列化的類對象T,做爲通用Dao接口的實現類實體類通用類型,可是在實現類的查詢中,也就是讀取中,咱們也須要獲取一個反射序列化的經過實體類對象模型,這就是須要反射的Class實例對象了,所以在通用DAO接口的實現類中,咱們須要建立一個Class實例對象,這個對象中咱們須要的泛型類型是反射序列化的實體類對象模型T,所以這個對象爲

Class<T> persistentClass;  

可是咱們還須要這個Class實例對象來獲取反射序列化的具體對象模型,這就須要咱們經過java底層對象類型來獲取了,具體爲

this.persistentClass=

(Class<T>)(ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];

這裏面1. getClass().getGenericSuperclass():獲取java最底層類對象  

2.
(ParameterizedType)getClass().getGenericSuperclass())
:轉換爲可序列化類型

3.
.getActualTypeArguments()[0] 
反射出第一個參數對象信息,也就是獲取類泛型中T extends Serializable

4.
(Class<T>)
:強轉爲當前類對象

經過這些複雜的過程,咱們能夠獲取反射序列化的具體Class實例類型,這樣就能夠經過該Class實例來獲取具體查詢的結果集合。

    所以實現類的代碼大體以下:

public class GenericHibernateDao<T extends Serializable,ID extends Serializable>

                     extends
HibernateDaoSupport 
implements
IGenericDao<T, ID> {

   Class<T> persistentClass;     

   public GenericHibernateDao() {

      //                強轉爲當前類對象,轉換爲可序列化類型,                       
獲取java最底層類對象                     反射出第一個參數對象信息                                               

      this.persistentClass=(Class<T>) ((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];

   }

   public Class<T> getPersistentClass() {

      return persistentClass;

   }

   public void setPersistentClass(Class<T> persistentClass) {

      this.persistentClass = persistentClass;

   }

   @Override

   public T create(T entity) {

      return (T) this.getHibernateTemplate().save(entity);

   }

   @Override

   public void delete(ID id) {

      //刪除通用方法                             參數爲要刪除的實體類對象

      System.out.println("IDD "+id);

      this.getHibernateTemplate().delete(this.findById(id));

   }

   @Override

   public void update(T entity) {

       this.getHibernateTemplate().update(entity);

   }

   @Override

   public T findById(ID id) {

      return this.getHibernateTemplate().get(persistentClass, id);

   }

   @Override

   public List<T> findAll() {

      return this.getHibernateTemplate().loadAll(persistentClass);

   }

   @Override

   public List<T> findByObject(String hql, Object[] param) {

      return this.getHibernateTemplate().find(hql, param);

   }

   @Override

   public PageBean findByPageBean(final String hql,final 
Object[] param,
final  int currentpage,final int pageSize) {

      return this.getHibernateTemplate().execute(new
HibernateCallback<PageBean>() {

         @Override

         public PageBean doInHibernate(Session session)throws
HibernateException, SQLException {

            //建立pagebean對象

            PageBean pb=new PageBean();

            //經過Query對象來獲取所須要頁的數據

            Query qu=session.createQuery(hql);

            //賦值參數

            if(param.length>0){

                for (int i = 0; i < param.length; i++) {

                   qu.setParameter(i, param[i]);

                }

            }

            //Query對象,賦值從第幾行到第幾行參數,也就是最大最小頁數值

            qu.setFirstResult((currentpage-1)*pageSize);

            qu.setMaxResults(pageSize);

            //PageBean對象,賦值list參數

            pb.setData(qu.list());

            //獲取總行數                               

            qu=session.createQuery("select count(*) "+hql.substring(hql.toLowerCase().indexOf("from")));

            //賦值獲取總行數參數

            if(param.length>0){

               for (int j = 0; j <
param.
length; j++) {                  
qu.setParameter(j, param[j]);

               }       

            }

            //Pagebean賦值總行數參數

            pb.setTotalRows(Integer.parseInt(qu.uniqueResult().toString()));

            //Pagebean賦值當前頁參數

            pb.setCurrentPage(currentpage);

            //Pagebean賦值每頁大小參數

            pb.setPageSize(pageSize);

            //返回pagebean對象

            return pb;

         }

      });

   }

   @Override

   public void bulkUpdate(String bulk, Object[] param) {

      this.getHibernateTemplate().bulkUpdate(bulk,param);

   }

   @Override

   public Integer countByObject(final String hql,final Object[] param) {

      return this.getHibernateTemplate().execute(new
HibernateCallback<Integer>() {

            //獲取hibernateSessionFactory接口方法  

         @Override

         public Integer doInHibernate(Session session)throws
HibernateException, SQLException {

            //經過HIbernateQuery方法來獲取count

            Query qu=session.createQuery(hql);

            for (int i = 0; i < param.length; i++) {

                qu.setParameter(i, param[i]);

            }

            return Integer.parseInt(qu.uniqueResult().toString());          

         }

      });

   }

}

以上是反射DAO模式的實現類及接口的核心代碼,經過具體的實體類對象來獲取具體的類對象集合,就能夠實現具體的經過DAO反射序列化的接口及實現類的效果。

做者:中軟卓越天津ETC

相關文章
相關標籤/搜索