?? basedaoimpl.java
字號:
package com.ponyjava.common.hibernate3;
import static org.hibernate.EntityMode.POJO;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Example.PropertySelector;
import org.hibernate.impl.CriteriaImpl;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.transform.ResultTransformer;
import org.hibernate.type.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;
import com.ponyjava.common.page.Pagination;
import com.ponyjava.common.util.MyBeanUtils;
/**
* DAO基類。
*
* 提供hql分頁查詢,example分頁查詢,拷貝更新等功能。
*
* @author liufang
*
* @param <T>
*/
@Repository
public abstract class BaseDaoImpl<T extends Serializable> implements BaseDao<T> {
protected Logger log = LoggerFactory.getLogger(getClass());
protected SessionFactory sessionFactory;
@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
protected Session getSession() {
return sessionFactory.getCurrentSession();
}
public T save(T entity) {
Assert.notNull(entity);
getSession().save(entity);
return entity;
}
public Object update(Object entity) {
Assert.notNull(entity);
getSession().update(entity);
return entity;
}
public Object saveOrUpdate(Object entity) {
Assert.notNull(entity);
getSession().saveOrUpdate(entity);
return entity;
}
public Object merge(Object entity) {
Assert.notNull(entity);
return getSession().merge(entity);
}
public void delete(Object entity) {
Assert.notNull(entity);
getSession().delete(entity);
}
public T deleteById(Serializable id) {
Assert.notNull(id);
T entity = load(id);
getSession().delete(entity);
return entity;
}
public T load(Serializable id) {
Assert.notNull(id);
return load(id, false);
}
@SuppressWarnings("unchecked")
public T get(Serializable id) {
Assert.notNull(id);
return (T) getSession().get(getPersistentClass(), id);
}
@SuppressWarnings("unchecked")
public T load(Serializable id, boolean lock) {
Assert.notNull(id);
T entity = null;
if (lock) {
entity = (T) getSession().load(getPersistentClass(), id,
LockMode.UPGRADE);
} else {
entity = (T) getSession().load(getPersistentClass(), id);
}
return entity;
}
public List<T> findAll() {
return findByCriteria();
}
@SuppressWarnings("unchecked")
public List<T> findAll(OrderBy... orders) {
Criteria crit = createCriteria();
if (orders != null) {
for (OrderBy order : orders) {
crit.addOrder(order.getOrder());
}
}
return crit.list();
}
public Pagination findAll(int pageNo, int pageSize, OrderBy... orders) {
Criteria crit = createCriteria();
return findByCriteria(crit, pageNo, pageSize, null, OrderBy
.asOrders(orders));
}
/**
* 按HQL查詢對象列表.
*
* @param hql
* hql語句
* @param values
* 數量可變的參數
*/
@SuppressWarnings("unchecked")
protected List find(String hql, Object... values) {
return createQuery(hql, values).list();
}
/**
* 按HQL查詢唯一對象.
*/
protected Object findUnique(String hql, Object... values) {
return createQuery(hql, values).uniqueResult();
}
/**
* 按屬性查找對象列表.
*/
@SuppressWarnings("unchecked")
public List<T> findByProperty(String propertyName, Object value) {
Assert.hasText(propertyName);
return createCriteria(Restrictions.eq(propertyName, value)).list();
}
/**
* 按屬性查找唯一對象.
*/
@SuppressWarnings("unchecked")
public T findUniqueByProperty(String propertyName, Object value) {
Assert.hasText(propertyName);
return (T) createCriteria(Restrictions.eq(propertyName, value))
.uniqueResult();
}
@SuppressWarnings("unchecked")
protected Pagination find(Finder finder, int pageNo, int pageSize) {
int totalCount = countQueryResult(finder);
Pagination p = new Pagination(pageNo, pageSize, totalCount);
if (totalCount < 1) {
p.setList(new ArrayList());
return p;
}
Query query = getSession().createQuery(finder.getOrigHql());
finder.setParamsToQuery(query);
query.setFirstResult(p.getFirstResult());
query.setMaxResults(p.getPageSize());
List list = query.list();
p.setList(list);
return p;
}
@SuppressWarnings("unchecked")
protected List find(Finder finder) {
Query query = getSession().createQuery(finder.getOrigHql());
finder.setParamsToQuery(query);
query.setFirstResult(finder.getFirstResult());
if (finder.getMaxResults() > 0) {
query.setMaxResults(finder.getMaxResults());
}
List list = query.list();
return list;
}
@SuppressWarnings("unchecked")
public List<T> findByEgList(T eg, boolean anyWhere, Condition[] conds,
String... exclude) {
Criteria crit = getCritByEg(eg, anyWhere, conds, exclude);
return crit.list();
}
@SuppressWarnings("unchecked")
public List<T> findByEgList(T eg, boolean anyWhere, Condition[] conds,
int firstResult, int maxResult, String... exclude) {
Criteria crit = getCritByEg(eg, anyWhere, conds, exclude);
crit.setFirstResult(firstResult);
crit.setMaxResults(maxResult);
return crit.list();
}
public Pagination findByEg(T eg, boolean anyWhere, Condition[] conds,
int page, int pageSize, String... exclude) {
Order[] orderArr = null;
Condition[] condArr = null;
if (conds != null && conds.length > 0) {
List<Order> orderList = new ArrayList<Order>();
List<Condition> condList = new ArrayList<Condition>();
for (Condition c : conds) {
if (c instanceof OrderBy) {
orderList.add(((OrderBy) c).getOrder());
} else {
condList.add(c);
}
}
orderArr = new Order[orderList.size()];
condArr = new Condition[condList.size()];
orderArr = orderList.toArray(orderArr);
condArr = condList.toArray(condArr);
}
Criteria crit = getCritByEg(eg, anyWhere, condArr, exclude);
return findByCriteria(crit, page, pageSize, null, orderArr);
}
/**
* 根據查詢函數與參數列表創建Query對象,后續可進行更多處理,輔助函數.
*/
protected Query createQuery(String queryString, Object... values) {
Assert.hasText(queryString);
Query queryObject = getSession().createQuery(queryString);
if (values != null) {
for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i, values[i]);
}
}
return queryObject;
}
/**
* 按Criterion查詢對象列表.
*
* @param criterion
* 數量可變的Criterion.
*/
@SuppressWarnings("unchecked")
protected List<T> findByCriteria(Criterion... criterion) {
return createCriteria(criterion).list();
}
@SuppressWarnings("unchecked")
protected Pagination findByCriteria(Criteria crit, int pageNo,
int pageSize, Projection projection, Order... orders) {
int totalCount = ((Number) crit.setProjection(Projections.rowCount())
.uniqueResult()).intValue();
Pagination p = new Pagination(pageNo, pageSize, totalCount);
if (totalCount < 1) {
p.setList(new ArrayList());
return p;
}
crit.setProjection(projection);
if (projection == null) {
crit.setResultTransformer(Criteria.ROOT_ENTITY);
}
if (orders != null) {
for (Order order : orders) {
crit.addOrder(order);
}
}
crit.setFirstResult(p.getFirstResult());
crit.setMaxResults(p.getPageSize());
p.setList(crit.list());
return p;
}
/**
* 通過count查詢獲得本次查詢所能獲得的對象總數.
*
* @param finder
* @return
*/
protected int countQueryResult(Finder finder) {
Query query = getSession().createQuery(finder.getRowCountHql());
finder.setParamsToQuery(query);
return ((Number) query.iterate().next()).intValue();
}
/**
* 通過count查詢獲得本次查詢所能獲得的對象總數.
*
* @return page對象中的totalCount屬性將賦值.
*/
@SuppressWarnings("unchecked")
protected int countQueryResult(Criteria c) {
CriteriaImpl impl = (CriteriaImpl) c;
// 先把Projection、ResultTransformer、OrderBy取出來,清空三者后再執行Count操作
Projection projection = impl.getProjection();
ResultTransformer transformer = impl.getResultTransformer();
List<CriteriaImpl.OrderEntry> orderEntries = null;
try {
orderEntries = (List) MyBeanUtils.getFieldValue(impl,
"orderEntries");
MyBeanUtils.setFieldValue(impl, "orderEntries", new ArrayList());
} catch (Exception e) {
log.error("不可能拋出的異常:{}", e.getMessage());
}
// 執行Count查詢
int totalCount = (Integer) c.setProjection(Projections.rowCount())
.uniqueResult();
if (totalCount < 1) {
return 0;
}
// 將之前的Projection和OrderBy條件重新設回去
c.setProjection(projection);
if (projection == null) {
c.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
}
if (transformer != null) {
c.setResultTransformer(transformer);
}
try {
MyBeanUtils.setFieldValue(impl, "orderEntries", orderEntries);
} catch (Exception e) {
log.error("不可能拋出的異常:{}", e.getMessage());
}
return totalCount;
}
protected Criteria getCritByEg(T bean, boolean anyWhere, Condition[] conds,
String... exclude) {
Criteria crit = getSession().createCriteria(getPersistentClass());
Example example = Example.create(bean);
example.setPropertySelector(NOT_BLANK);
if (anyWhere) {
example.enableLike(MatchMode.ANYWHERE);
example.ignoreCase();
}
for (String p : exclude) {
example.excludeProperty(p);
}
crit.add(example);
// 處理排序和is null字段
if (conds != null) {
for (Condition o : conds) {
if (o instanceof OrderBy) {
OrderBy order = (OrderBy) o;
crit.addOrder(order.getOrder());
} else if (o instanceof Nullable) {
Nullable isNull = (Nullable) o;
if (isNull.isNull()) {
crit.add(Restrictions.isNull(isNull.getField()));
} else {
crit.add(Restrictions.isNotNull(isNull.getField()));
}
} else {
// never
}
}
}
// 處理many to one查詢
ClassMetadata cm = getCmd(bean.getClass());
String[] fieldNames = cm.getPropertyNames();
for (String field : fieldNames) {
Object o = cm.getPropertyValue(bean, field, POJO);
if (o == null) {
continue;
}
ClassMetadata subCm = getCmd(o.getClass());
if (subCm == null) {
continue;
}
Serializable id = subCm.getIdentifier(o, POJO);
if (id != null) {
Serializable idName = subCm.getIdentifierPropertyName();
crit.add(Restrictions.eq(field + "." + idName, id));
} else {
crit.createCriteria(field).add(Example.create(o));
}
}
return crit;
}
public void refresh(Object entity) {
getSession().refresh(entity);
}
public Object updateDefault(Object entity) {
return updateByUpdater(Updater.create(entity));
}
public Object updateByUpdater(Updater updater) {
ClassMetadata cm = getCmd(updater.getBean().getClass());
if (cm == null) {
throw new RuntimeException("所更新的對象沒有映射或不是實體對象");
}
Object bean = updater.getBean();
Object po = getSession().load(bean.getClass(),
cm.getIdentifier(bean, POJO));
updaterCopyToPersistentObject(updater, po);
return po;
}
/**
* 將更新對象拷貝至實體對象,并處理many-to-one的更新。
*
* @param updater
* @param po
*/
@SuppressWarnings("unchecked")
private void updaterCopyToPersistentObject(Updater updater, Object po) {
Map map = MyBeanUtils.describe(updater.getBean());
Set<Map.Entry<String, Object>> set = map.entrySet();
for (Map.Entry<String, Object> entry : set) {
String name = entry.getKey();
Object value = entry.getValue();
if (!updater.isUpdate(name, value)) {
continue;
}
if (value != null) {
Class valueClass = value.getClass();
ClassMetadata cm = getCmd(valueClass);
if (cm != null) {
Serializable vid = cm.getIdentifier(value, POJO);
// 如果更新的many to one的對象的id為空,則將many to one設置為null。
if (vid != null) {
value = getSession().load(valueClass, vid);
} else {
value = null;
}
}
}
try {
PropertyUtils.setProperty(po, name, value);
} catch (Exception e) {
// never
log.warn("更新對象時,拷貝屬性異常", e);
}
}
}
/**
* 根據Criterion條件創建Criteria,后續可進行更多處理,輔助函數.
*/
protected Criteria createCriteria(Criterion... criterions) {
Criteria criteria = getSession().createCriteria(getPersistentClass());
for (Criterion c : criterions) {
criteria.add(c);
}
return criteria;
}
private Class<T> persistentClass;
@SuppressWarnings("unchecked")
public BaseDaoImpl() {
this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}
public Class<T> getPersistentClass() {
return persistentClass;
}
public T createNewEntiey() {
try {
return getPersistentClass().newInstance();
} catch (Exception e) {
throw new RuntimeException("不能創建實體對象:"
+ getPersistentClass().getName());
}
}
@SuppressWarnings("unchecked")
private ClassMetadata getCmd(Class clazz) {
return (ClassMetadata) sessionFactory.getClassMetadata(clazz);
}
public static final NotBlankPropertySelector NOT_BLANK = new NotBlankPropertySelector();
/**
* 不為空的EXAMPLE屬性選擇方式
*
* @author liufang
*
*/
static final class NotBlankPropertySelector implements PropertySelector {
private static final long serialVersionUID = 1L;
public boolean include(Object object, String propertyName, Type type) {
return object != null
&& !(object instanceof String && StringUtils
.isBlank((String) object));
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -