SSH整合(4)之延迟加载问题&抽取通用Dao

SSH整合(4)之延迟加载问题&抽取通用Dao

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:

延迟加载问题

Hibernate 是有延迟加载策略的,Spring 整合 Hibernate 后,session 的是由 Spring 管理的。当我们做一个有延迟加载的查询操作时,默认情况下在 service 层已经完成了 session 的开启与关闭操作,所以如果我们要在 Web 层使用延迟加载,此时 session 是关闭的状态,会抛出如下异常:

image.png

对于这个问题 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);
    }
}

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.zze.xyz/archives/ssh4.html

Buy me a cup of coffee ☕.