getHibernateTemplate的使用與介紹

最近系統中使用了ssh,對dao層的封裝,在這裏簡單介紹下。java

一、咱們以前若是不使用spring的話,採用hibernate來操做數據庫的時候,一般須要使用一個sessionfactory(線程安全)來建立session(線程不安全)。而後來進行crud操做以後,再關閉session。事務,關閉session,包括hql了這些都須要本身手動來處理。spring

spring封裝的getHibernateTemplate則更加方便,將增刪改查都封裝好了。sql

使用getSession()方法你只要繼承 sessionFactory,而使用getHibernateTemplate()方法必須繼承HibernateDaoSupport固然包括 sessionFactory,這點區別都不是特別重要的,下面這些區別就很重要了數據庫

二、getSession()方法是沒有通過spring包裝 的,spring會把最原始的session給你,在使用完以後必須本身調用相應的close方法,並且也不會對聲明式事務進行相應的管理,一旦沒有及時 關閉鏈接,就會致使數據庫鏈接池的鏈接數溢出,getHibernateTemplate()方法是通過spring封裝的,例如添加相應的聲明式事務管 理,由spring管理相應的鏈接。apache

在實際的使用過程當中發現的確getHibernateTemplate()比getSession()方法要好不少,可是有些方法在getHibernateTemplate()並無提供,這時咱們用HibernateCallback 回調的方法管理數據庫.緩存

如下爲本項目中封裝的baseDao安全

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
 
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.util.Assert;
 
import com.newtouch.system.core.utils.GenericsUtils;
 
/**
 * Description: 純Hibernate Entity DAO基類. 經過泛型,子類無需擴展任何函數即擁有完整的CRUD操做.
 * 
 * @author,
 */
 
abstract public class AbstractHibernateDao<T> extends HibernateDaoSupport {
 
    protected Log logger = LogFactory.getLog(getClass());
    /**
     * 定義一個限制用戶數據的過濾器CREATED_BY_USER 須要配合 <hibernate-mapping> <class > <filter
     * name="FilterByUser" condition=":CREATED_BY_USER=CREATED_BY_USER">
     * </filter> </class> <filter-def name="FilterByUser"> <filter-param
     * name="CREATED_BY_USER" type="string"/> </filter-def> </hibernate-mapping>
     * 來使用
     */
    protected String FILTER_BY_USER = "FilterByUser";
 
    /**
     * 開啓根據用戶登陸名來限制用戶只能查看到本身的數據限制
     * 
     * @param userLoginName
     */
    public void enableFilterUser(String userLoginName) {
 
        try {
            getSession(true).enableFilter(FILTER_BY_USER).setParameter("CREATED_BY_USER", userLoginName);
        } catch (DataAccessResourceFailureException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * Dao所管理的Entity類型.
     */
    protected Class<T> entityClass;
 
    /**
     * 取得entityClass的函數. 不支持泛型的子類能夠拋開Class<T> entityClass,從新實現此函數達到相同效果。
     */
    public Class<T> getEntityClass() {
        return entityClass;
    }
 
    /**
     * 在構造函數中將泛型T.class賦給entityClass
     */
    public AbstractHibernateDao() {
        entityClass = GenericsUtils.getGenericClass(getClass());
    }
 
    /**
     * 根據id獲取對象 
     * 
     * 1.get()方法在一級緩存沒有找到會直接查詢數據庫,不會去二級緩存中查找
     * 2.get()若是在數據庫中沒有記錄會返回空,get()不管如何都會返回數據. 
     * @param id
     * @return Object
     */
    @SuppressWarnings("unchecked")
    public T get(Serializable id) {
        T o = (T) getHibernateTemplate().get(getEntityClass(), id);
        if (o == null)
            throw new ObjectRetrievalFailureException(getEntityClass(), id);
        return o;
    }
 
    /**
     * 獲取全部對象列表 
     * 
     * @param
     * @return List
     */
    @SuppressWarnings("unchecked")
    public List<T> loadAll() {
        return getHibernateTemplate().loadAll(getEntityClass());
    }
 
    /**
     * 根據id獲取對象
     * 1.load()方法會使用二級緩存
     * 2.load():若是數據庫中沒有記錄會拋出異常,若是有數據返回的是一個代理對象。 
     * @param id
     * @return
     */
     
    public T Load(Serializable id) {
        T o = (T) getHibernateTemplate().load(getEntityClass(), id);
        if (o == null)
            throw new ObjectRetrievalFailureException(getEntityClass(), id);
        return o;
    }
  
    /**
     * 獲取指定數量的對象
     * 
     * @param entityClass
     * @return
     * @throws DataAccessException
     */
    public List<T> getSpecifyNumObj(final int num) {
        getHibernateTemplate().setFetchSize(0);
        getHibernateTemplate().setMaxResults(num);
        return getHibernateTemplate().loadAll(getEntityClass());
    }
 
    /**
     * 新增或更新對象
     * 
     * @param entity
     * @return 
     */
    public void saveOrUpdate(Object entity) {
        getHibernateTemplate().saveOrUpdate(entity);
    }
 
    /**
     * 新增對象
     * 
     * @param entity
     */
    public void save(Object entity) {
        getHibernateTemplate().save(entity);
    }
 
    /**
     * 修改對象
     * 
     * @param entity
     */
    public void update(Object entity) {
        getHibernateTemplate().update(entity);
    }
 
    /**
     * @deprecated ,使用此方法無法經過aop類記錄日誌 根據ID刪除單個對象
     * @param id
     */
    public void removeById(String id) {
        Object obj = (Object) get(id);
        if (null != obj) {
            remove(obj);
        }
    }
 
    /**
     * 刪除一個對象
     * 
     * @param o
     */
    public void remove(Object entity) {
            getHibernateTemplate().delete(entity);
    }
 
    /**
     * 刪除全部對象
     * 
     * @param entities
     */
    public void removeAll(final Collection entities) {
        getHibernateTemplate().deleteAll(entities);
    }
 
    //**********************************//
    //如下查詢全都返回List//
    //**********************************//
    /**
     * 根據HSQL來查找
     * 
     * @param hsql
     * @return
     */
    public List<T> find(String hsql) {
        return getHibernateTemplate().find(hsql);
    }
 
    /**
     * 根據HSQL和給定的一個值來查詢
     * 
     * @param hsql
     * @param value
     * @return
     */
    public List<T> find(String hsql, Object value) {
        return getHibernateTemplate().find(hsql, value);
    }
 
    /**
     * 根據HSQL和給定的一組值來查詢
     * 
     * @param hsql
     * @param values
     * @return
     */
    public List<T> find(String hsql, Object[] values) {
        return getHibernateTemplate().find(hsql, values);
    }
 
    /**
     * 根據屬性名和屬性值查詢對象.等值查詢
     * 
     * @return 符合條件的惟一對象
     */
    public T findUniqueBy(String name, Object value) {
        Criteria criteria = getSession().createCriteria(getEntityClass());
        if (StringUtils.isNotEmpty(name))
            criteria.add(Restrictions.eq(name, value));
        return (T) criteria.uniqueResult();
    }
 
    /**
     * 根據屬性名和屬性值查詢對象.等值查詢
     * 
     * @return 符合條件的對象列表
     */
    public List<T> findBy(String name, Object value) {
        Assert.hasText(name);
        Criteria criteria = getSession().createCriteria(getEntityClass());
        criteria.add(Restrictions.eq(name, value));
        return criteria.list();
    }
 
    /**
     * 根據屬性名和屬性值以Like AnyWhere方式查詢對象.
     */
    public List<T> findByLike(String name, String value) {
        Assert.hasText(name);
        Criteria criteria = getSession().createCriteria(getEntityClass());
        criteria.add(Restrictions.like(name, value, MatchMode.ANYWHERE));
        return criteria.list();
    }
 
    /**
     * 根據Map中過濾條件進行查詢.
     * 
     * @param filter
     *            過濾條件.
     * @param setUpCriteriaMethodName
     *            將Map中條件轉換爲criteria的函數名,支持子類對Map中的條件有多種處理方法.
     */
    public List<T> findBy(Map<String, Object> filter, CriteriaSetup criteriaSetup) {
        Criteria criteria = getEntityCriteria();
        criteriaSetup.setup(criteria, filter);
        try{
            return criteria.list();
        }catch(Exception e){
            return null;
        }
    }
 
    /**
     * 函數做用同{@link #findBy(Map)} 若是不須要分頁,子類可直接重載此函數.
     * 若是有分頁,儘可能從CriteriaSetup繼承建立新的子類.
     * 
     */
    public List<T> findBy(Map<String, Object> filter) {
        return findBy(filter, CriteriaSetup.EQUAL);
    }
 
    /**
     * 根據filter中過濾條件進行查詢,查詢結果根據sortMap排序
     * @param filter
     * @param sortMap
     * @param criteriaSetup
     * @return
     */
    public List<T> findBy(Map<String, Object> filter,Map<String,String> sortMap,CriteriaSetup criteriaSetup){
        Criteria criteria = getEntityCriteria();
        sortCriteria(criteria,sortMap,null);
        criteriaSetup.setup(criteria, filter);
        return criteria.list();
    }
    public List<T> findByLike(Map<String, Object> filter) {
        return findBy(filter, CriteriaSetup.LIKE);
    }
 
    protected CriteriaSetup getDefaultCriteriaSetup() {
        return CriteriaSetup.EQUAL;
    }
 
    /**
     * 取得Entity的Criteria.
     */
    protected Criteria getEntityCriteria() {
        return getSession().createCriteria(getEntityClass());
    }
 
    /**
     * 構造Criteria的排序條件默認函數.可供其餘查詢函數調用
     * 
     * @param criteria
     *            Criteria實例.
     * @param sortMap
     *            排序條件.
     * @param entity
     *            entity對象,用於使用反射來獲取某些屬性信息
     */
    protected void sortCriteria(Criteria criteria, Map sortMap, Object entity) {
        if (!sortMap.isEmpty()) {
            for (Object obj : sortMap.keySet()) {
                String fieldName = obj.toString();
                String orderType = sortMap.get(fieldName).toString();
 
                // 處理嵌套屬性如category.name,modify_user.id,暫時只處理一級嵌套
                if (fieldName.indexOf('.') != -1) {
                    String alias = StringUtils.substringBefore(fieldName, ".");
                    String aliasType = alias;
                    try {
                        aliasType = PropertyUtils.getProperty(entity, alias).getClass().getSimpleName();
                    } catch (Exception e) {
                        logger.error("Get property" + alias + " error",e);
                    }
                    criteria.createAlias(aliasType, alias);
                }
 
                if ("asc".equalsIgnoreCase(orderType)) {
                    criteria.addOrder(Order.asc(fieldName));
                } else {
                    criteria.addOrder(Order.desc(fieldName));
                }
            }
        }
    }
 
    /**
     * 判斷對象某列的值在數據庫中不存在重複
     * 
     * @param names
     *            在POJO裏相對應的屬性名,列組合時以逗號分割
     *            如"name,loginid,password"
     */
    public boolean isNotUnique(T entity, String names) {
        Assert.hasText(names);
        Criteria criteria = getSession().createCriteria(entityClass).setProjection(Projections.rowCount());
        String[] nameList = names.split(",");
        try {
            for (String name : nameList) {
                criteria.add(Restrictions.eq(name, PropertyUtils.getProperty(entity, name)));
            }
 
            String idName = getSessionFactory().getClassMetadata(entityClass).getIdentifierPropertyName();
            if (idName != null) {
                Object idValue = PropertyUtils.getProperty(entity, idName);
                // 若是是update,排除自身
                if (idValue != null && idValue.toString().length() > 0)
                    criteria.add(Restrictions.not(Restrictions.eq(idName, idValue)));
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            return false;
        }
        return ((Integer) criteria.uniqueResult()) > 0;
    }
 
    /**
     * 是否存在字段名爲name,值爲value的重複記錄,且id值爲idValue的記錄除外 前提條件是查找的entity類型與dao對應的T相同
     * 
     * @param idValue
     * @param name
     * @param value
     * @return
     */
    public boolean isNotUnique(String idValue, String name, String value) {
        Assert.notNull(idValue);
        Assert.notNull(name);
        Assert.notNull(value);
        Criteria criteria = getSession().createCriteria(entityClass).setProjection(Projections.rowCount());
        try {
            criteria.add(Restrictions.eq(name, value));
 
            String idName = getSessionFactory().getClassMetadata(entityClass).getIdentifierPropertyName();
            if (idName != null) {
                // 若是是update,排除自身
                if (idValue != null)
                    criteria.add(Restrictions.not(Restrictions.eq(idName, idValue)));
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            return false;
        }
        return ((Integer) criteria.uniqueResult()) > 0;
    }
}
相關文章
相關標籤/搜索