代码分层导致Hibernate懒加载失效的问题我认为没有必要考虑

14-03-22 zhaozeyang
解决失效方案列举
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修改过]