使用HibernateDaoSupport抽取BaseDao


        在開發采用Struts2+Spring+hibernate這三大框架的項目時,我們需要一個抽取一個BaseDao。這個Dao里面CRUD都給封裝好, 后續的其他Dao直接用它的功能就可以。Spring里面有個HibernateDaoSupport的類,這個類需要給他一個SessionFactory。 有了SessionFactory后, 他就可以做各種操作;最強大的功能是它可以getHibernateTemplate來獲取一個HibernateTemplate。有了HibernateTemplate,就有了各種CRUD方法。廢話不多說,下面直接看代碼

一、BaseDao接口及實現的代碼

     (1)BaseDao接口的代碼
package com.tax.core.dao;
import java.io.Serializable; 
import java.util.List;

/**
 * BaseDao
 * @author ZENG.XIAO.YAN
 * @date 2017年6月29日 上午10:36:57
 * @version v1.0
 */
public interface BaseDao<T> {

	/**
	 * 新增
	 * @param entity
	 */
	public void save(T entity);

	/**
	 * 更新
	 * @param entity
	 */
	public void update(T entity);

	/**
	 * 根據id刪除
	 * @param id
	 */
	public void deleteById(Serializable id);

	
	/**
	 * 通過id查找
	 * @param id
	 * @return 實體
	 */
	public T findById(Serializable id);

	
	/**
	 * 查找所有
	 * @return List集合
	 */
	public List<T> findAll();
}
    
    (2)BaseDaoImpl的代碼

package com.tax.core.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import com.tax.core.dao.BaseDao;

/**
 * BaseDaoImpl
 * @author   ZENG.XIAO.YAN
 * @date 	 2017年6月29日 下午12:23:16
 * @version  v1.0
 */
public abstract class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
	
	private Class<T> clazz;
	
	// 按照類型自動注入SessionFactory; 在實例化的時候,Spring按照形參的類型自動注入
	@Autowired
	public void setMySessionFactory(SessionFactory sessionFactory){
		setSessionFactory(sessionFactory);
	}
	
	
	public BaseDaoImpl() {
		//this表示當前被實例化的對象;如UserDaoImpl
		ParameterizedType pt = (ParameterizedType)this.getClass().getGenericSuperclass();//BaseDaoImpl<User> 
		clazz = (Class<T>)pt.getActualTypeArguments()[0];
	}
	
	/**
	 * 獲取session
	 * @return session
	 */
	public Session getCurrentSession(){
		Session session = null;
		try {
			session = getSessionFactory().getCurrentSession();
		} catch (HibernateException e) {
			throw new RuntimeException("getCurrentSession error", e);
			//session = getSessionFactory().openSession();
		}
		return session;
	}
	
	@Override
	public void save(T entity) {
		getHibernateTemplate().save(entity);
	}
	
	@Override
	public void update(T entity) {
		getHibernateTemplate().update(entity);
	}
	
	@Override
	public void deleteById(Serializable id) {
		getHibernateTemplate().delete(findById(id));
	}
	
	@Override
	public T findById(Serializable id) {
		return getHibernateTemplate().get(clazz, id);
	}
	@Override
	public List<T> findAll() {
		Session session = getCurrentSession();
		Query query = session.createQuery("FROM "+ clazz.getSimpleName());
		return query.list();
	}

}

    (3)對BaseDaoImpl的說明
            使用HibernateDaoSupport需要注入SessionFactorytory,這個注入的動作其實可以交給BaseDaoImpl的子類去完成的。
            如:StudentImpl繼承了BaseDaoImpl。那么在Spring的xml文件按照下面配置即可
                    
            但是:我覺得這樣很麻煩,而且我Dao層我想直接用注解。我不想在每個Dao里都去寫這個注入的動作。
            所以就准備在BaseDaoImpl里面去完成這個注入動作。
            下面開始了我的探索之路:
             方案一: 在BaseDaoImpl里面定義SessionFactory的屬性,然后屬性用注解把它注入。
                            最后在構造器里把這個SessionFactory通過set給HibernateDaoSupport。
                            具體的如下圖:
                            
                            結果:雖然想法沒問題,但是后面發現在實例化的時候,這個sessionFactory還沒注進來。
                                       在項目啟動的是時候就報錯了,因為我給別人的SessionFactory個設置為null了;所以失敗了。
                            后面通過百度發現,原來 Spring容器管理的類中,這個@Autowired注入是在對象實例化完成之后
                            所以對Spring容器對bean的實例化過程的還是需要掌握的,筆者在這塊掌握得不好。
                            參考鏈接: http://blog.csdn.net/xia744510124/article/details/51273576

            方案二:  在BaseDaoImpl中定義一個方法,在方法上加個注解。然后方法中把注解注入的形參(sessionFactory)
                                 通過set給HibernateDaoSupport。
                           具體如下圖:
                           
                            結果: 注入成功,這個注解是根據形參的類型自動注入的。sessionFactory會在Spring實例化這Dao后注入。
                           參考鏈接: http://blog.csdn.net/tsingheng/article/details/8847047

            通過這個探索,發現了自己對Spring的知識掌握得不夠,不知道用注解來注入是在對象實例化之后。
                    

 二、使用寫好的BaseDao和BaseImpl

        (1)Dao接口直接繼承BaseDao即可,下面以StudentDao接口為例
                 
       (2)Dao的實現類,需要繼承BaseDaoImpl,下面以StudentDaoImpl為例
                 

三、結束語

        通過抽取這個BaseDao,后續的CRUD就很方便了。
 

 


                           
 


    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM