程式碼分層導致Hibernate懶載入失效的問題我認為沒有必要考慮

zhaozeyang發表於2014-03-22
解決失效方案列舉
1.openSessionView 擴大作用域,影響效能,不用
2.在DAO層把需要的初始化,程式碼量大,不採用
3.泛型模版類提供回撥介面,傳入匿名內部物件呼叫初始化,可以採用(自己想的,勉強使用)

但是我認為考慮這個根本沒必要

我的解決方案是這樣的:

Hibernate 配置:
根據業務,常用的欄位需要join的就fetch=join,不需要的就開lazy,fetch=select
如果某個實體內的一些欄位內,只有某些少數業務查詢需要fetch=join,其他大部分都不需要這部分資料的時候,建議配置檔案開lazy,fetch=select,特殊查詢全用HQL指定left join fetch來抓取指定欄位,下面會說道

使用DAO泛型模板類, 提供各類基礎的查詢模版方法,也提供懶載入的回撥介面,方便初始化懶載入的資料,(解決程式碼分層session關閉後懶載入失效的問題)這個偶爾使用,一般很少使用這些回撥的介面,
因為特殊的關聯查詢我全用模板類提供的HQL查詢的模版方法了,而HQL是可以指定特殊欄位的抓取方式的。

比方說 from Teacher as t left join fetch t.(某個關聯物件) 直接JOIN抓取了,
而直接from Teacher就是預設懶載入,另外值得一提的是HQL查詢裡你配置裡的抓取方式全無效,預設全是lazy+select,需要在程式碼裡指定

反正都要用的資料,直接Join查出來不一樣的嗎,
就算是偶爾碰到未初始化的代理物件,用回撥介面來給它初始化吧


另外附上我的模版類的介面

public interface GenericDaoI<T extends Serializable> {

	/**
	 * 回撥介面,初始化代理物件用
	 * 
	 * @[author]author[/author] zhaozeyang
	 * 
	 */
	public interface InitializeObjCallBack<T> {
		public void initializeObj(final T obj);
	}

	/**
	 * 回撥介面,初始化代理物件LIST用
	 * 
	 * @[author]author[/author] zhaozeyang
	 * 
	 */
	public interface InitializeListCallBack<T> {
		public void initializeList(final List<T> ls);
	}

	/**
	 * 新增一條資料
	 * 
	 * @param entity
	 *            實體
	 */
	public abstract void create(final T entity);

	/**
	 * 新增一條資料 若存在則更新
	 * 
	 * @param entity
	 */
	public abstract void createOrUpdate(final T entity);

	/**
	 * 根據主鍵查實體
	 * 
	 * @param id
	 *            主鍵
	 * @return 查詢結果
	 */
	public abstract T findById(final Serializable id);

	/**
	 * 根據主鍵查實體
	 * 
	 * @param id
	 * @param callback
	 *            回撥介面
	 * @return
	 */
	public abstract T findById(final Serializable id,
			InitializeObjCallBack<T> callback);

	/**
	 * 根據id刪資料,可傳多個id
	 * 
	 * @param entityids
	 *            id序列
	 */
	public abstract void deleteById(Serializable... entityids);

	/**
	 * 更新實體類到資料庫
	 * 
	 * @param entity
	 *            要更新的實體類
	 */
	public abstract void update(final T entity);

	/**
	 * 查所有記錄
	 * 
	 * @return 查詢結果
	 */
	public abstract List<T> findAll();

	/**
	 * 查所有記錄
	 * 
	 * @param callBack
	 *            回撥介面
	 * @return
	 */
	public abstract List<T> findAll(InitializeListCallBack<T> callBack);

	/**
	 * HQL查記錄
	 * 
	 * @param strHQL
	 *            HQL語句
	 * @param params
	 *            引數
	 * @return 查詢結果
	 */
	public abstract List<T> findByHQL(final String strHQL,
			final Object... params);

	/**
	 * HQL查記錄
	 * 
	 * @param callBack
	 *            回撥介面
	 * @param strHQL
	 *            HQL語句
	 * @param params
	 *            引數
	 * @return 查詢結果
	 */
	public abstract List<T> findByHQL(InitializeListCallBack<T> callBack,
			final String strHQL, final Object... params);

	/**
	 * HQL分頁查詢
	 * 
	 * @param strHQL
	 *            HQL語句
	 * @param currentPage
	 *            查第幾頁
	 * @param pageSize
	 *            一個頁面資料的條數
	 * @param params
	 *            查詢結果
	 * @return
	 */
	public abstract PageBean<T> findByPage(final String strHQL,
			final int currentPage, final int pageSize, final Object... params);

	/**
	 * HQL分頁查詢
	 * 
	 * @param callBack
	 *            回撥介面
	 * @param strHQL
	 * @param currentPage
	 * @param pageSize
	 * @param params
	 * @return
	 */
	public abstract PageBean<T> findByPage(InitializeListCallBack<T> callBack,
			final String strHQL, final int currentPage, final int pageSize,
			final Object... params);

	/**
	 * 用Criteria方式查詢資料
	 * 
	 * @param prams
	 * @return
	 */
	public List<T> findByCriteria(Criterion... prams);

	/**
	 * 用Criteria方式查詢資料
	 * 
	 * @param callBack
	 *            回撥介面
	 * @param prams
	 * @return
	 */
	public List<T> findByCriteria(InitializeListCallBack<T> callBack,
			Criterion... prams);

	public Integer getCount();
<p class="indent">

[該貼被zhaozeyang於2014-03-22 21:49修改過]

[該貼被zhaozeyang於2014-03-22 21:52修改過]

[該貼被zhaozeyang於2014-03-22 22:09修改過]

[該貼被zhaozeyang於2014-03-22 22:12修改過]

相關文章