延迟加载问题
Hibernate 是有延迟加载策略的,Spring 整合 Hibernate 后,session 的是由 Spring 管理的。当我们做一个有延迟加载的查询操作时,默认情况下在 service 层已经完成了 session 的开启与关闭操作,所以如果我们要在 Web 层使用延迟加载,此时 session 是关闭的状态,会抛出如下异常:
对于这个问题 Spring 也给我们提供了解决方案,只需要配置上它提供的一个过滤器即可,如下:
<!-- WEB-INF/web.xml -->
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
抽取通用Dao
抽取通用接口:
// com.zze.dao.BaseDao
package com.zze.dao;
import org.hibernate.criterion.DetachedCriteria;
import java.io.Serializable;
import java.util.List;
public interface BaseDao<T> {
/**
* 保存操作
*
* @param model 要保存的模型
*/
void save(T model);
/**
* 更新操作
*
* @param model 要更新的模型
*/
void update(T model);
/**
* 删除操作
*
* @param id 删除的 id
*/
void delete(Serializable id);
/**
* 通过 id 查询单个对象
*
* @param id 要删除数据主键
* @return 返回 id 对应的单个对象
*/
T findById(Serializable id);
/**
* 查询所有数据
*
* @return 以 List 方式返回所有数据
*/
List<T> findAll();
/**
* 查询数据条数
*
* @param detachedCriteria 离线查询对象
* @return 数据条数
*/
Serializable findCount(DetachedCriteria detachedCriteria);
/**
* 分页查询
*
* @param detachedCriteria 离线查询对象
* @param begin 数据起始索引
* @param pageSize 每页数据条数
* @return 返回分页的珊瑚橘
*/
List<T> findPage(DetachedCriteria detachedCriteria, Integer begin, Integer pageSize);
}
创建该接口的实现类:
// com.zze.dao.impl.BaseDaoImpl
package com.zze.dao.impl;
import com.zze.dao.BaseDao;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
private Class clazz;
public BaseDaoImpl() {
/*
例: class UserDaoImpl extends BaseDaoImpl<User>
*/
// 获取到运行时实际类 UserDaoImpl
Class<? extends BaseDaoImpl> actualClass = this.getClass();
// 获取到实际类父类 BaseDaoImpl<User>
Type genericSuperclass = actualClass.getGenericSuperclass();
// 转为参数化类型
ParameterizedType type = (ParameterizedType) genericSuperclass;
// 获取类型化参数 User
Type[] actualTypeArguments = type.getActualTypeArguments();
this.clazz = (Class) actualTypeArguments[0];
}
@Override
public void save(T model) {
this.getHibernateTemplate().save(model);
}
@Override
public void update(T model) {
this.getHibernateTemplate().update(model);
}
@Override
public void delete(Serializable id) {
this.getHibernateTemplate().delete(id);
}
@Override
public T findById(Serializable id) {
return (T) this.getHibernateTemplate().get(clazz, id);
}
@Override
public List<T> findAll() {
return (List<T>) this.getHibernateTemplate().find("from " + clazz.getSimpleName());
}
@Override
public Serializable findCount(DetachedCriteria detachedCriteria) {
detachedCriteria.setProjection(Projections.rowCount());
List<Long> list = (List<Long>) this.getHibernateTemplate().findByCriteria(detachedCriteria);
return list.size() > 0 ? list.get(0).intValue() : null;
}
@Override
public List<T> findPage(DetachedCriteria detachedCriteria,Integer begin,Integer pageSize) {
detachedCriteria.setProjection(null);
return (List<T>) this.getHibernateTemplate().findByCriteria(detachedCriteria, begin, pageSize);
}
}
评论区