在 Hibernate4 中使用HibernateDaoSupport

最近公司的项目要升级Hibernate, 把原来的Hibernate 3.5 升级到 Hibernate 4.2.11. But... 项目原来的Dao层都直接使用了getHibernateTemplate(), 是因为BaseDao继承org.springframework.orm.hibernate3.HibernateTemplate .可是整个项目200+Dao类, 要一个一个改么? 万一改错了怎么办?


最后还是去重新实现HibernateDaoSupport吧. 这样的好处就是, 改动比较小, 不需要所有的Dao类都去改, 如果改这么多的话, 很容易出错, 如果我们让Hibernate4 继续使用HibernateDaoSupport的话, 那么就可以集中修改啦. 

0x00 准备工作

除了将pom.xml中的hibernate, spring相关的依赖升级之外, 我们还需要去GrepCode看看源码. 那么就开始吧.

0x01 新建HibernateDaoSupport类

新建一个HibernateDaoSupport, 然后使我们原来的BaseDao继承我们新建的HibernateDaoSupport
package net.wechance.dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * <p>
 * 重新实现HibernateDaoSupport
 * </p>
 * @author <a href="mailto:williamsun1993@gmail.com">William Suen</a> 
 */
public class HibernateDaoSupport {
    
    private HibernateTemplate hibernateTemplate;

    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }
    
    @Autowired
    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }
    
    public SessionFactory getSessionFactory() {
        return hibernateTemplate.getSessionFactory();
    }
    
    public Session getSession() {
        return getSessionFactory().getCurrentSession();
    }
}

0x02 Spring中注入hibernateTemplate

<bean id="hibernateTemplate" class="net.wechance.dao.HibernateTemplate" />

0x03 新建HibernateTemplate类

这里的话, 根据需要添加相应的方法吧, 缺哪个补哪个, 具体源码看GrepCode的.
package net.wechance.dao;


import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;


import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.transaction.support.TransactionSynchronizationManager;


import com.sinba.common.util.Assert;


/**
 * Helper class that simplifies Hibernate data access code. Automatically
 * converts HibernateExceptions into DataAccessExceptions, following the
 * <code>org.springframework.dao</code> exception hierarchy.
 *
 * <p>The central method is <code>execute</code>, supporting Hibernate access code
 * implementing the {@link HibernateCallback} interface. It provides Hibernate Session
 * handling such that neither the HibernateCallback implementation nor the calling
 * code needs to explicitly care about retrieving/closing Hibernate Sessions,
 * or handling Session lifecycle exceptions. For typical single step actions,
 * there are various convenience methods (find, load, saveOrUpdate, delete).
 * 
 * @author <a href="mailto:<span style="font-family: Arial, Helvetica, sans-serif;">williamsun1993@gmail.com</span><span style="font-family: Arial, Helvetica, sans-serif;">">William Suen</a> </span>
 *
 */
public class HibernateTemplate {
    
    private SessionFactory sessionFactory;
    
    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }


    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }


    private Session getCurrentSession() {
        Object value = TransactionSynchronizationManager.getResource(getSessionFactory());
        if (null == value) {
            return sessionFactory.openSession();
        } else {
            return this.sessionFactory.getCurrentSession();            
        }
    }
    
    public <T> T execute(HibernateCallback<T> action) throws DataAccessException {
        return doExecute(action, false, false);
    }
    
    public List executeFind(HibernateCallback<?> action) throws DataAccessException {
        Object result = doExecute(action, false, false);
        Assert.isTrue((result != null && result instanceof List), "Result object returned from HibernateCallback isn't a List: [" + result + "]");
        return (List) result;
    }
    
    /**
     * Execute the action specified by the given action object within a Session.
     * @param action callback object that specifies the Hibernate action
     * @param enforceNewSession whether to enforce a new Session for this template
     * even if there is a pre-bound transactional Session
     * @param enforceNativeSession whether to enforce exposure of the native
     * Hibernate Session to callback code
     * @return a result object returned by the action, or <code>null</code>
     * @throws org.springframework.dao.DataAccessException in case of Hibernate errors
     */
    protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNewSession, boolean enforceNativeSession)
            throws DataAccessException {
        Assert.notNull(action, "Callback object must not be null");
        T result = null;
        try {
            result = action.doInHibernate(getCurrentSession());
        } catch (HibernateException e) {
            throw new IllegalArgumentException(e);
        } catch (SQLException e) {
            throw new IllegalArgumentException(e);
        }
        return result;
    }
    
    
    //-------------------------------------------------------------------------
    // Convenience methods for loading individual objects
    //-------------------------------------------------------------------------
    
    public <T> T get(Class<T> entityClass, Serializable id) throws DataAccessException {
        return get(entityClass, id, null);
    }
    
    public <T> T get(final Class<T> entityClass, final Serializable id, final LockMode lockMode)
            throws DataAccessException {
        if (lockMode != null) {
            return (T) getCurrentSession().get(entityClass, id, lockMode);
        } else {
            return (T) getCurrentSession().get(entityClass, id);
        }
    }
    
    public <T> T load(Class<T> entityClass, Serializable id) throws DataAccessException {
        return load(entityClass, id, null);
    }


    public <T> T load(final Class<T> entityClass, final Serializable id, final LockMode lockMode)
            throws DataAccessException {
        if (lockMode != null) {
            return (T) getCurrentSession().load(entityClass, id, lockMode);
        } else {
            return (T) getCurrentSession().load(entityClass, id);
        }
    }
    
    //-------------------------------------------------------------------------
    // Convenience methods for storing individual objects
    //-------------------------------------------------------------------------
    
    public Serializable save(final Object entity) throws DataAccessException {
        return getCurrentSession().save(entity);
    }
    
    public void saveOrUpdate(final Object entity) throws DataAccessException {
        getCurrentSession().saveOrUpdate(entity);
    }
    
    public void saveOrUpdateAll(final Collection entities) throws DataAccessException {
        for (Object entity : entities) {
            getCurrentSession().saveOrUpdate(entity);
        }
    }
    
    public <T> T merge(final T entity) throws DataAccessException {
        return (T) getCurrentSession().merge(entity);
    }
    
    public void delete(final Object entity) throws DataAccessException {
        getCurrentSession().delete(entity);
    }
    
    public void deleteAll(final Collection entities) throws DataAccessException {
        for (Object entity : entities) {
            getCurrentSession().delete(entity);
        }
    }
    
    //-------------------------------------------------------------------------
    // Convenience finder methods for HQL strings
    //-------------------------------------------------------------------------
    
    public List find(String queryString) throws DataAccessException {
        return find(queryString, (Object[]) null);
    }
    
    public List find(String queryString, Object value) throws DataAccessException {
        return find(queryString, new Object[] {value});
    }
    
    public List find(final String queryString, final Object... values) throws DataAccessException {
        Query queryObject = getCurrentSession().createQuery(queryString);
        if (values != null) {
            for (int i = 0; i < values.length; i++) {
                queryObject.setParameter(i, values[i]);
            }
        }
        return queryObject.list();
    }
    
    public List findByNamedParam(
            final String queryString, 
            final String paramName, 
            final Object value) throws DataAccessException {
        return findByNamedParam(queryString, new String[] {paramName}, new Object[] {value});
    }
    
    public List findByNamedParam(
            final String queryString, 
            final String[] paramNames, 
            final Object[] values) throws DataAccessException {
        
        Assert.isTrue(paramNames.length == values.length, "Length of paramNames array must match length of values array");
        Query query = getCurrentSession().createQuery(queryString);
        if (values != null) {
            for (int i = 0, size = values.length; i < size; i++) {
                applyNamedParameterToQuery(query, paramNames[i], values[i]);
            }
        }
        return query.list();
    }
    
    //-------------------------------------------------------------------------
    // Convenience finder methods for detached criteria
    //-------------------------------------------------------------------------
    
    public List findByCriteria(DetachedCriteria criteria) throws DataAccessException {
        return findByCriteria(criteria, -1, -1);
    }
    
    public List findByCriteria(final DetachedCriteria criteria, final int firstResult, final int maxResults) {
        Criteria executableCriteria = criteria.getExecutableCriteria(getCurrentSession());
        if (firstResult >= 0) {
            executableCriteria.setFirstResult(firstResult);
        }
        if (maxResults > 0) {
            executableCriteria.setMaxResults(maxResults);
        }
        return executableCriteria.list();
    }
    
    /**
     * Apply the given name parameter to the given Query object.
     * @param queryObject the Query object
     * @param paramName the name of the parameter
     * @param value the value of the parameter
     * @throws HibernateException if thrown by the Query object
     */
    protected void applyNamedParameterToQuery(Query queryObject, String paramName, Object value) 
            throws HibernateException {
    
        if (value instanceof Collection) {
            queryObject.setParameterList(paramName, (Collection) value);
        } else if (value instanceof Object[]) {
            queryObject.setParameterList(paramName, (Object[]) value);
        } else {
            queryObject.setParameter(paramName, value);
        }
    }
}


以上通过测试的. 总之最重要的还是HibernateTemplate这个类. 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值