package com.mossle.core.hibernate;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.mossle.core.id.IdGenerator;
import com.mossle.core.page.Page;
import com.mossle.core.query.MatchType;
import com.mossle.core.query.PropertyFilter;
import com.mossle.core.util.GenericsUtils;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
/**
* 使用泛型的hibernate基类.
*
* @author Lingo
* @param <T>
* 实体类型
*/
public class HibernateEntityDao<T> extends HibernatePagingDao {
/** logger. */
private static Logger logger = LoggerFactory
.getLogger(HibernateEntityDao.class);
/** 持久类的类型. */
private Class<T> entityClass;
/** 构造方法. */
public HibernateEntityDao() {
this.entityClass = GenericsUtils.getSuperClassGenericType(this
.getClass());
}
/**
* constructor.
*
* @param sessionFactory
* SessionFactory
*/
public HibernateEntityDao(SessionFactory sessionFactory) {
this();
super.setSessionFactory(sessionFactory);
}
/**
* constructor.
*
* @param sessionFactory
* SessionFactory
* @param entityClass
* Class
*/
public HibernateEntityDao(SessionFactory sessionFactory,
Class<T> entityClass) {
super(sessionFactory);
this.entityClass = entityClass;
}
/**
* 子类可以获得泛型对应的实体类型.
*
* @return entityClass
*/
public Class<T> getEntityClass() {
return entityClass;
}
/**
* @param entityClass
* Class.
*/
public void setEntityClass(Class<T> entityClass) {
this.entityClass = entityClass;
}
// ============================================================================================
// get, load, getAll, save, remove, removeById, removeAll
// ============================================================================================
/**
* 获得一个实体类型的一条记录.
*
* @param id
* 主键
* @return 实例
*/
@Transactional(readOnly = true)
public T get(Serializable id) {
return this.get(this.entityClass, id);
}
/**
* load一个实例,如果id不存在,会返回一个proxy,在调用proxy的时候出现问题. 使用这个方法,可以利用缓存,但是如果实例不存在,会出现不容易预计的错误
*
* @param id
* 主键
* @return 实例
*/
@Transactional(readOnly = true)
public T load(Serializable id) {
return this.load(this.entityClass, id);
}
/**
* 获得一个实体类型的所有记录.
*
* @return 所有实例列表
*/
@Transactional(readOnly = true)
public List<T> getAll() {
return this.getAll(this.entityClass);
}
/**
* 获得所有记录,带排序参数.
*
* @param orderBy
* 排序字段名
* @param isAsc
* 是否正序排列
* @return 返回结果列表
*/
@Transactional(readOnly = true)
public List<T> getAll(String orderBy, boolean isAsc) {
return this.getAll(this.entityClass, orderBy, isAsc);
}
/**
* 根据主键删除记录.
*
* @param id
* 主键
*/
@Transactional
public void removeById(Serializable id) {
this.remove(this.get(id));
}
/**
* 删除所有记录.
*/
@Transactional
public void removeAll() {
this.removeAll(this.getAll());
}
@Transactional
@Override
public void save(Object entity) {
this.save(entity, this.getIdGenerator());
}
@Transactional
public void save(Object entity, IdGenerator idGenerator) {
try {
boolean isCreated = getId(entity.getClass(), entity) == null;
if (idGenerator != null) {
if (isCreated) {
String idFieldName = getIdName(entity.getClass());
Serializable id = getIdGenerator().generateId();
if (id != null) {
setId(entity.getClass(), entity, id);
}
super.insert(entity);
} else {
super.update(entity);
}
} else {
super.save(entity);
}
if (isCreated) {
publishEvent(new EntityCreatedEvent(entity));
} else {
publishEvent(new EntityUpdatedEvent(entity));
}
} catch (NoSuchMethodException ex) {
logger.warn(ex.getMessage(), ex);
super.save(entity);
} catch (IllegalAccessException ex) {
logger.warn(ex.getMessage(), ex);
super.save(entity);
} catch (InvocationTargetException ex) {
logger.warn(ex.getMessage(), ex);
super.save(entity);
}
}
@Transactional
@Override
public void remove(Object entity) {
super.remove(entity);
publishEvent(new EntityRemovedEvent(entity));
}
// ============================================================================================
// createCriteria
// ============================================================================================
/**
* 根据entityClass生成对应类型的Criteria.
*
* @param criterions
* 条件
* @return Criteria
*/
public Criteria createCriteria(Criterion... criterions) {
return this.createCriteria(this.entityClass, criterions);
}
/**
* 根据entityClass,生成带排序的Criteria.
*
* @param orderBy
* 排序字段名
* @param isAsc
* 是否正序
* @param criterions
* 条件
* @return Criteria
*/
public Criteria createCriteria(String orderBy, boolean isAsc,
Criterion... criterions) {
return this
.createCriteria(this.entityClass, orderBy, isAsc, criterions);
}
// ============================================================================================
// findBy
// ============================================================================================
/**
* 根据name,value进行查询.
*
* @param name
* 字段名
* @param value
* 参数值
* @return 查询结果
*/
@Transactional(readOnly = true)
public List<T> findBy(String name, Object value) {
return this.findBy(this.entityClass, name, value);
}
/**
* find by ids.
*
* @param entityClass
* Class
* @param ids
* List
* @param <T>
* generic
* @return List
*/
@Transactional(readOnly = true)
public List<T> findByIds(List ids) {
return this.findByIds(entityClass, ids);
}
/**
* 根据name,value进行模糊查询.
*
* @param name
* 字段名
* @param value
* 用来做模糊查询的字段值
* @return 查询结果
*/
@Transactional(readOnly = true)
public List<T> findByLike(String name, Object value) {
return this.findByLike(this.entityClass, name, value);
}
/**
* 查询唯一记录.
*
* @param name
* 字段名
* @param value
* 字段值
* @return 实例
*/
@Transactional(readOnly = true)
public T findUniqueBy(String name, Object value) {
return this.findUniqueBy(this.entityClass, name, value);
}
// ============================================================================================
// getCount
// ============================================================================================
/**
* 获得总记录数.
*
* @return 总数
*/
@Transactional(readOnly = true)
public Integer getCount() {
return this.getCount(this.entityClass);
}
// ============================================================================================
// pagedQuery
// ============================================================================================
/**
* 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.
*
* @param pageNo
* 当前页号
* @param pageSize
* 每页最大记录数
* @param criterions
* 条件
* @return 含总记录数和当前页数据的Page对象.
*/
@Transactional(readOnly = true)
public Page pagedQuery(int pageNo, int pageSize, Criterion... criterions) {
return this.pagedQuery(this.entityClass, pageNo, pageSize, criterions);
}
/**
* 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.
*
* @param pageNo
* 当前页号
* @param pageSize
* 每页最大记录数
* @param orderBy
* 排序字段名
* @param isAsc
* 是否正序
* @param criterions
* 条件
* @return 含总记录数和当前页数据的Page对象.
*/
@Transactional(readOnly = true)
public Page pagedQuery(int pageNo, int pageSize, String orderBy,
boolean isAsc, Criterion... criterions) {
logger.debug("start");
return this.pagedQuery(this.entityClass, pageNo, pageSize, orderBy,
isAsc, criterions);
}
// ============================================================================================
// PropertyFilter
// ============================================================================================
/**
* findBy.
*
* @param propertyName
* String
* @param propertyValue
* Object
* @param matchType
* MatchType
* @return List
*/
public List<T> findBy(String propertyName, Object propertyValue,
MatchType matchType) {
return find(this.entityClass, HibernateUtils.buildCriterion(
propertyName, propertyValue, matchType));
}
/**
* find.
*
* @param propertyFilters
* list
* @return List
*/
public List<T> find(List<PropertyFilter> propertyFilters) {
return find(this.entityClass,
HibernateUtils.buildCriterion(propertyFilters));
}
/**
* pagedQuery.
*
* @param pageNo
* int
* @param pageSize
* int
* @param propertyFilters
* list
* @return page
*/
public Page pagedQuery(int pageNo, int pageSize,
List<PropertyFilter> propertyFilters) {
return pagedQuery(this.entityClass, pageNo, pageSize,
HibernateUtils.buildCriterion(propertyFilters));
}
/**
* pagedQuery.
*
* @param page
* Page
* @param propertyFilters
* list
* @return page
*/
public Page pagedQuery(Page page, List<PropertyFilter> propertyFilters) {
return pagedQuery(this.entityClass, page,
HibernateUtils.buildCriterion(propertyFilters));
}
// ~ ======================================================================
// hql
public Page pagedQuery(String hql, Page page,
List<PropertyFilter> propertyFilters) {
return pagedQuery(hql, page.getPageNo(), page.getPageSize(),
propertyFilters);
}
public Page pagedQuery(String hql, int pageNo, int pageSize,
List<PropertyFilter> propertyFilters) {
StringBuilder buff = new StringBuilder(hql);
Map<String, Object> map = new HashMap<String, Object>();
for (PropertyFilter propertyFilter : propertyFilters) {
HibernateUtils.buildQuery(buff, propertyFilter);
String key = propertyFilter.getPropertyName()
.replaceAll("\\.", "_");
map.put(key, propertyFilter.getMatchValue());
}
return pagedQuery(buff.toString(), pageNo, pageSize, map);
}
}