一、咱們以前若是不使用spring的話,採用hibernate來操做數據庫的時候,一般須要使用一個sessionfactory(線程安全)來建立session(線程不安全)。而後來進行crud操做以後,再關閉session。事務,關閉session,包括hql了這些都須要本身手動來處理。spring
使用getSession()方法你只要繼承 sessionFactory,而使用getHibernateTemplate()方法必須繼承HibernateDaoSupport固然包括 sessionFactory,這點區別都不是特別重要的,下面這些區別就很重要了數據庫
二、getSession()方法是沒有通過spring包裝 的,spring會把最原始的session給你,在使用完以後必須本身調用相應的close方法,並且也不會對聲明式事務進行相應的管理,一旦沒有及時 關閉鏈接,就會致使數據庫鏈接池的鏈接數溢出,getHibernateTemplate()方法是通過spring封裝的,例如添加相應的聲明式事務管 理,由spring管理相應的鏈接。apache
在實際的使用過程當中發現的確getHibernateTemplate()比getSession()方法要好不少,可是有些方法在getHibernateTemplate()並無提供,這時咱們用HibernateCallback 回調的方法管理數據庫.緩存
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;
}
}