package org.exitsoft.orm.core.hibernate;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.exitsoft.common.utils.CollectionUtils;
import org.exitsoft.common.utils.ConvertUtils;
import org.exitsoft.common.utils.ReflectionUtils;
import org.exitsoft.orm.annotation.StateDelete;
import org.exitsoft.orm.core.PageRequest.Sort;
import org.exitsoft.orm.enumeration.ExecuteMehtod;
import org.exitsoft.orm.strategy.CodeStrategy;
import org.exitsoft.orm.strategy.annotation.ConvertCode;
import org.exitsoft.orm.strategy.annotation.ConvertProperty;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.LockOptions;
import org.hibernate.Query;
import org.hibernate.ReplicationMode;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.hibernate.internal.CriteriaImpl;
import org.hibernate.jdbc.Work;
import org.hibernate.metadata.ClassMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
/**
*
* Hibernate基础类,包含对Hibernate的CURD和其他Hibernate操作
*
* @author vincent
*
* @param <T> ROM对象
* @param <PK> ORM主键ID类型
*/
public class BasicHibernateDao<T,PK extends Serializable> {
protected SessionFactory sessionFactory;
protected Class<T> entityClass;
protected final String DEFAULT_ALIAS = "X";
private static Logger logger = LoggerFactory.getLogger(BasicHibernateDao.class);
/**
* 构造方法
*/
public BasicHibernateDao() {
entityClass = ReflectionUtils.getSuperClassGenricType(getClass());
}
/**
* 构造方法
*
* @param entityClass orm实体类型class
*/
public BasicHibernateDao(Class<T> entityClass) {
this.entityClass = entityClass;
}
/**
* 设置Hibernate sessionFactory
*
* @param sessionFactory
*/
@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
/**
* 获取Hibernate SessionFactory
*
* @return {@link SessionFactory}
*/
public SessionFactory getSessionFactory() {
return sessionFactory;
}
/**
* 取得当前Session.
*
* @return {@link Session}
*/
public Session getSession() {
return sessionFactory.getCurrentSession();
}
/**
* 对修改orm实体前的处理, 如果orm实体不为null返回true,并且将该orm实体进行转码,否则返回flase,
*
* @param entity orm实体
* @param executeMehtods
*
* @return boolean
*/
private boolean preproModifyEntity(T entity,ExecuteMehtod... executeMehtods) {
if (entity == null) {
return false;
}
convertObject(entity, executeMehtods);
return true;
}
/**
* 新增对象.
*
* @param entity orm实体
*/
public void insert(T entity) {
if (!preproModifyEntity(entity,ExecuteMehtod.Insert)) {
return ;
}
getSession().save(entity);
}
/**
* 批量新增对象
*
* @param list orm实体集合
*/
public void insertAll(List<T> list) {
if (CollectionUtils.isEmpty(list)) {
return ;
}
for (Iterator<T> it = list.iterator(); it.hasNext();) {
insert(it.next());
}
}
/**
* 更新对象
* @param entity orm实体
*/
public void update(T entity) {
if (!preproModifyEntity(entity,ExecuteMehtod.Update)) {
return ;
}
getSession().update(entity);
}
/**
* 批量更新对象
* @param list orm实体集合
*/
public void updateAll(List<T> list) {
if (CollectionUtils.isEmpty(list)) {
return ;
}
for (Iterator<T> it = list.iterator(); it.hasNext();) {
update(it.next());
}
}
/**
* 新增或修改对象
*
* @param entity orm实体
*/
public void save(T entity) {
if (!preproModifyEntity(entity, ExecuteMehtod.Save)) {
return ;
}
getSession().saveOrUpdate(entity);
}
/**
* 保存或更新全部对象
*
* @param list orm实体集合
*/
public void saveAll(List<T> list) {
if (CollectionUtils.isEmpty(list)) {
return ;
}
for (Iterator<T> it = list.iterator(); it.hasNext();) {
save(it.next());
}
}
/**
* 删除对象.
*
* @param entity 对象必须是session中的对象或含PK属性的transient对象.
*/
public void deleteByEntity(T entity) {
if (entity == null) {
logger.warn("要删除的对象为:null");
return ;
}
StateDelete stateDelete = ReflectionUtils.getAnnotation(entity.getClass(),StateDelete.class);
if (stateDelete != null) {
Object value = ConvertUtils.convertToObject(stateDelete.value(), stateDelete.type().getValue());
ReflectionUtils.invokeSetterMethod(entity, stateDelete.propertyName(), value);
update(entity);
} else {
getSession().delete(entity);
}
}
/**
* 按PK删除对象.
*
* @param id 主键ID
*/
public void delete(PK id) {
deleteByEntity(get(id));
}
/**
* 按PK批量删除对象
*
* @param ids 主键ID集合
*/
public void deleteAll(List<PK> ids) {
if (CollectionUtils.isEmpty(ids)) {
return ;
}
for (Iterator<PK> it = ids.iterator(); it.hasNext();) {
delete(it.next());
}
}
/**
* 按orm实体集合删除对象
* @param list
*/
public void deleteAllByEntities(List<T> list) {
if (!CollectionUtils.isEmpty(list)) {
return ;
}
for (Iterator<T> it = list.iterator(); it.hasNext();) {
deleteByEntity(it.next());
}
}
/**
* 按PK获取对象实体.如果找不到对象或者id为null值时,返回null,参考{@link Session#get(Class, Serializable)}
*
* @see Session#get(Class, Serializable)
*
* @param id 主键ID
*
*/
public T get(PK id) {
if (id == null) {
return null;
}
return (T) getSession().get(entityClass, id);
}
/**
* 按PK获取对象代理.如果id为null,返回null。参考{@link Session#load(Class, Serializable)}
*
* @see Session#load(Class, Serializable)
*
* @param id 主键ID
*
*/
public T load(PK id) {
if (id == null) {
return null;
}
return (T) getSession().load(entityClass, id);
}
/**
* 按PK列表获取对象列表.
*
* @param ids 主键ID集合
*
* @return List
*/
public List<T> get(Collection<PK> ids) {
if (CollectionUtils.isEmpty(ids)) {
return Collections.emptyList();
}
return createCriteria(Restrictions.in(getIdName(), ids)).list();
}
/**
* 按PK列表获取对象列表.
*
* @param ids 主键ID数据
*
* @return List
*/
public List<T> get(PK[] ids) {
return createCriteria(Restrictions.in(getIdName(), ids)).list();
}
/**
* 取得对象的主键名.
*
* @return String
*/
public String getIdName() {
ClassMetadata meta = sessionFactory.getClassMetadata(entityClass);
return meta.getIdentifierPropertyName();
}
/**
* 获取实体名称
*
* @return String
*/
public String getEntityName() {
ClassMetadata meta = sessionFactory.getClassMetadata(entityClass);
return meta.getEntityName();
}
/**
* 获取全部对象.
*
* @return List
*/
public List<T> getAll() {
return createCriteria().list();
}
/**
* 通过HQL查询全部。参数形式为命名参数形式
* <pre>
* from Object o where o.property1 = :property1 and o.property2 = :proerty2
* </pre>
*
* @param queryString hql语句
* @param values 与属性名方式的hql值
*
* @return List
*/
public <X> List<X> findByQuery(String queryString,Map<String,Object> values) {
return createQuery(queryString, values).list();
}
/**
* 通过HQL查询全部.参数形式为jdbc参数形式:
* <pre>
* //使用是jdbc参数风格(问号后面没有带顺序值)
* from object o where o.property = ? and o.property = ?
* </pre>
*
* @param queryString hql语句
* @param values 可变长度的hql值
*
* @return List
*/
public <X> List<X> findByQuery(String queryString,Object... values) {
return createQuery(queryString, values).list();
}
/**
* 通过HQL查询全部.参数形式为jpa风格形式:
* <pre>
* //使用是jpa参数风格(问号后面带顺序值"?1")
* from object o where o.property = ?1 and o.property = ?2
* </pre>
*
* @param queryString hql语句
* @param values 可变长度的hql值
*
* @return List
*/
public <X> List<X> findByQueryUseJpaStyle(String queryString,Object... values) {
return createQueryUseJpaStyle(queryString, values).list();
}
/**
* 通过queryNamed查询全部。参数形式为命名参数形式
* <pre>
* from Object o where o.property1 = :property1 and o.property2 = :proerty2
* </pre>
*
* @param queryNamed queryNamed
* @param values 属性名参数规则
*
* @return List
*/
public <X> List<X> findByQueryNamed(String queryNamed,Map<String, Object> values) {
return createQueryByQueryNamed(queryNamed, values).list();
}
/**
* 通过queryNamed查询全部,参数形式为jdbc参数形式:
* <pre>
* //使用是jdbc参数风格(问号后面没有带顺序值)
* from object o where o.property = ? and o.property = ?
* </pre>
*
* @param queryNamed queryNamed
* @param values 值
*
* @return List
*/
public <X> List<X> findByQueryNamed(String queryNamed,Object... values) {
return createQueryByQueryNamed(queryNamed, values).list();
}
/**
* 通过queryNamed查询全部,参数形式为jpa风格形式:
* <pre>
* //使用是jpa参数风格(问号后面带顺序值"?1")
* from object o where o.property = ?1 and o.property = ?2
* </pre>
*
* @param queryNamed queryNamed
* @param values 值
*
* @return List
*/
public <X> List<X> findByQueryNamedUseJpaStyle(String queryNamed,Object... values) {
return createQueryByQueryNamedUseJpaStyle(queryNamed, values).list();
}
/**
* 通过hql查询单个orm实体,参数形式为命名参数形式
* <pre>
* from Object o where o.property1 = :property1 and o.property2 = :proerty2
* </pre>
*
* @param queryString hql
* @param values 以属性名的hql值
*
* @return Object
*/
public <X> X findUniqueByQuery(String queryString,Map<String, Object> values){
return (X)createQuery(queryString, values).uniqueResult();
}
/**
* 通过hql查询单个orm实体,参数形式为jdbc参数形式:
* <pre>
* //使用是jdbc参数风格(问号后面没有带顺序值)
* from object o where o.property = ? and o.property = ?
* </pre>
*
* @param queryString hql
* @param values 可变长度的hql值
*
* @return Object
*/
public <X> X findUniqueByQuery(String queryString,Object... values){
return (X)createQuery(queryString, values).uniqueResult();
}
/**
* 通过hql查询单个orm实体,参数形式为jpa风格形式:
*
* <pre>
* //使用是jpa参数风格(问号后面带顺序值"?1")
* from object o where o.property = ?1 and o.property = ?2
* </pre>
*
* @param queryString hql
* @param values 以属性名的hql值
*
* @return Object
*/
public <X> X findUniqueByQueryUseJpaStyle(String queryString,Object... values){
return (X)createQueryUseJpaStyle(queryString, values).uniqueResult();
}
/**
* 通过QueryName查询单个orm实体,参数形式为命名参数形式
* <pre>
* from Object o where o.property1 = :property1 and o.property2 = :proerty2
* </pre>
*
* @param queryName queryName
* @param values 属性名参数规则
*
* @return Object
*/
public <X> X findUniqueByQueryNamed(String queryNamed,Map<String, Object> values) {
return (X)createQueryByQueryNamed(queryNamed, values).uniqueResult();
}
/**
* 通过QueryName查询单个orm实体,参数形式为jdbc参数形式:
* <pre>
* //使用是jdbc参数风格(问号后面没有带顺序值)
* from object o where o.property = ? and o.property = ?
* </pre>
*
* @param queryName queryName
* @param values 值
*
* @return Object
*/
public <X> X findUniqueByQueryNamed(String queryNamed,Object... values) {
return (X) createQueryByQueryNamed(queryNamed, values).uniqueResult();
}
/**
* 通过QueryName查询单个orm实体,该QueryName参数形式为jpa风格形式:
*
* <pre>
* //该QueryName使用是jpa参数风格(问号后面带顺序值"?1")
* rom object o where o.property = ?1 and o.property = ?2
* </pre>
*
* @param queryName queryName
* @param values 值
*
* @return Object
*/
public <X> X findUniqueByQueryNamedUseJapStyle(String queryNamed,Object... values) {
return (X) createQueryByQueryNamedUseJpaStyle(queryNamed, values).uniqueResult();
}
/**
* 获取全部对象
*
* @param orderByProperty 要排序的字段名称
* @param isAsc 是否顺序排序 true表示顺序排序,false表示倒序
*
* @return List
*/
public List<T> getAll(String orderByProperty, boolean isAsc) {
Criteria c = createCriteria();
setOrderToCriteria(c, isAsc ? Sort.ASC : Sort.DESC);
return c.list();
}
/**
* 获取实体的总记录数
*
* @return int
*/
public int entityCount() {
return countHqlResult("from " + getEntityName() + " " + DEFAULT_ALIAS).intValue();
}
/**
* 根据Criterion可变数组创建Criteria对象
*
* @param criterions 可变长度的Criterion数组
*
* @return {@link Criteria}
*/
protected Criteria createCriteria(Criterion... criterions) {
return createCriteria(this.entityClass,criterions);
}
/**
* 根据Criterion可变数组创建Criteria对象
*
* @param criterions 可变长度的Criterion数组
* @param orderBy 排序表达式,规则为:属性名称_排序规则,如:property_asc或property_desc,可以支持多个属性排序,用逗号分割,如:"property1_asc,proerty2_desc",也可以"property"不加排序规则时默认是desc
*
* @return {@link Criteria}
*/
protected Criteria createCriteria(String orderBy,Criterion... criterions) {
return createCriteria(this.entityClass, orderBy,criterions);
}
/**
* 根据Criterion可变数组创建Criteria对象
*
* @param persistentClass orm实体class
* @param criterions 可变长度的Criterion数组
*
* @return {@link Criteria}
*/
protected Criteria createCriteria(Class<?> persistentClass,Criterion... criterions) {
return createCriteria(persistentClass,StringUtils.EMPTY,criterions);
}
/**
* 根据Criterion可变数组创建Criteria对象
*
* @param persistentClass orm实体class
* @param orderBy 排序表达式,规则为:属性名称_排序规则,如:property_asc或property_desc,可以支持多个属性排序,用逗号分割,如:"property1_asc,proerty2_desc",也可以"property"不加排序规则时默认是desc
* @param criterions 可变长度的Criterion数组
*
* @return @return {@link Criteria}
*/
protected Criteria createCriteria(Class<?> persistentClass,String orderBy,Criterion... criterions) {
Criteria criteria = getSession().createCriteria(persistentClass);
for (Criterion criterion :criterions) {
criteria.add(criterion);
}
setOrderToCriteria(criteria,orderBy);
return criteria;
}
/**
* 根据DetachedCriteria创建Criteria对象
*
* @param detachedCriteria Hibernate DetachedCriteria
*
* @return @return {@link Criteria}
*/
protected Criteria createCriteria(DetachedCriteria detachedCriteria) {
return detachedCriteria.getExecutableCriteria(getSession());
}
/**
* 根据Criterion可变数组创建DetachedCriteria对象
*
* @param criterions 可变长度的Criterion数组
*
* @return @return {@link DetachedCriteria}
*/
protected DetachedCriteria createDetachedCriteria(Criterion... criterions) {
return createDetachedCriteria(this.entityClass,null,criterions);
}
/**
* 根据Criterion可变数组创建DetachedCriteria对象
*
* @param orderBy 排序表达式,规则为:属性名称_排序规则,如:property_asc或property_desc,可以支持多个属性排序,用逗号分割,如:"property1_asc,proerty2_desc",也可以"property"不加排序规则时默认是desc
* @param criterions 可变长度的Criterion数组
*
* @return @return {@link DetachedCriteria}
*/
protected DetachedCriteria createDetachedCriteria(String orderBy,Criterion... criterions) {
return createDetachedCriteria(this.entityClass,orderBy,criterions);
}
/**
* 根据Criterion可变数组创建DetachedCriteria对象
*
* @param persistentClass orm实体class
* @param orderBy 排序表达式,规则为:属性名称_排序规则,如:property_asc或property_desc,可以支持多个属性排序,用逗号分割,如:"property1_asc,proerty2_desc",也可以"property"不加排序规则时默认是desc
* @param criterions 可变长度的Criterion数组
*
* @return @return {@link DetachedCriteria}
*/
protected DetachedCriteria createDetachedCriteria(Class<?> persistentClass,String orderBy,Criterion... criterions) {
DetachedCriteria criteria = DetachedCriteria.forClass(persistentClass);
for (Criterion criterion :criterions) {
criteria.add(criterion);
};
CriteriaImpl criteriaImpl = ReflectionUtils.getFieldValue(criteria, "impl");
setOrderToCriteria(criteriaImpl,orderBy);
return criteria;
}
/**
* 根据查询HQL与参数列表创建Query对象,参数形式为命名参数形式:
* <pre>
* //使用的是命名参数风格
* from object o where o.condition = :condition
* </pre>
*
* @param values
* 命名参数,按名称绑定.
*
* @return {@link Query}
*
*/
protected Query createQuery( String queryString, Map<String, ?> values) {
Assert.hasText(queryString, "queryString不能为空");
Query query = getSession().createQuery(queryString);
if (values != null) {
query.setProperties(values);
}
return query;
}
/**
* 根据hql创建Hibernate Query对象,参数形式为jdbc参数形式:
* <pre>
* //使用是jdbc参数风格(问号后面没有带顺序值)
* from object o where o.property = ? and o.property = ?
* </pre>
*
* @param queryString hql
* @param values
* 数量可变的参数,按顺序绑定.
*
* @return {@link Query}
*/
protected Query createQuery(String queryString, Object... values) {
Assert.hasText(queryString, "queryString不能为空");
Query query = getSession().createQuery(queryString);
setQueryValues(query, values);
return query;
}
/**
* 根据hql创建Hibernate Query对象,参数形式为jpa风格形式:
* <pre>
* //使用是jpa参数风格(问号后面带顺序值"?1")
* from object o where o.property = ?1 and o.property = ?2
* </pre>
*
* @param queryNamed queryNamed
* @param values 值
*
* @return {@link Query}
*/
protected Query createQueryUseJpaStyle(String queryString,Object... values) {
Assert.hasText(queryString, "queryString不能为空");
Query query = getSession().createQuery(queryString);
setQueryValuesByJpaStley(query, values);
return query;
}
/**
* 通过queryNamed 创建Query,参数形式为命名参数形式:
* <pre>
* //使用的是命名参数风格
* from object o where o.condition = :condition
* </pre>
*
* @param queryNamed queryNamed
* @param values 属性名参数规则
*
* @return {@link Query}
*/
protected Query createQueryByQueryNamed(String queryNamed,Map<String, Object> values) {
Query query = getSession().getNamedQuery(queryNamed);
if (values != null) {
query.setProperties(values);
}
return query;
}
/**
* 通过queryNamed创建Query。参数形式为jdbc参数形式:
* <pre>
* //使用是jdbc参数风格(问号后面没有带顺序值)
* from object o where o.property = ? and o.property = ?
* </pre>
*
* @param queryNamed queryNamed
* @param values 值
*
* @return {@link Query}
*/
protected Query createQueryByQueryNamed(String queryNamed,Object... values) {
Assert.hasText(queryNamed, "QueryNamed不能为空");
Query query = getSession().getNamedQuery(queryNamed);
setQueryValues(query, values);
return query;
}
/**
* 根据queryNamed创建Hibernate Query对象,参数形式为jpa风格形式:
* <pre>
* //使用是jpa参数风格(问号后面带顺序值"?1")
* from object o where o.property = ?1 and o.property = ?2
* </pre>
*
* @param queryNamed queryNamed
* @param values 值
*
* @return {@link Query}
*/
protected Query createQueryByQueryNamedUseJpaStyle(String queryNamed,Object... values) {
Query query = getSession().getNamedQuery(queryNamed);
setQueryValuesByJpaStley(query, values);
return query;
}
/**
* 根据查询HQL与参数列表创建Query对象,数形式为命名参数形式:
* <pre>
* //使用的是命名参数风格
* from object o where o.condition = :condition
* </pre>
*
* @param values
* 命名参数,按名称绑定.
*
* @return {@link Query}
*
*/
protected SQLQuery createSQLQuery( String queryString, Map<String, ?> values) {
Assert.hasText(queryString, "queryString不能为空");
SQLQuery query = getSession().createSQLQuery(queryString);
if (values != null) {
query.setProperties(values);
}
return query.addEntity(entityClass);
}
/**
* 根据查询SQL与参数列表创建SQLQuery对象,参数形式为jdbc参数形式:
* <pre>
* //使用是jdbc参数风格(问号后面没有带顺序值)
* from object o where o.property = ? and o.property = ?
* </pre>
*
* @param values
* 数量可变的参数,按顺序绑定.
*
* @return {@link SQLQuery}
*/
protected SQLQuery createSQLQuery( String queryString, Object... values) {
Assert.hasText(queryString, "queryString不能为空");
SQLQuery query = getSession().createSQLQuery(queryString);
setQueryValues(query, values);
return query.addEntity(entityClass);
}
/**
* 根据查询SQL与参数列表创建SQLQuery对象,参数形式为jpa风格形式:
* <pre>
* //使用是jpa参数风格(问号后面带顺序值"?1")
* from object o where o.property = ?1 and o.property = ?2
* </pre>
*
* @param values
* 数量可变的参数,按顺序绑定.
*
* @return {@link SQLQuery}
*/
protected SQLQuery createSQLQueryUseJpaStyle( String queryString, Object... values) {
Assert.hasText(queryString, "queryString不能为空");
SQLQuery query = getSession().createSQLQuery(queryString);
setQueryValuesByJpaStley(query, values);
return query.addEntity(entityClass);
}
/**
* 通过orm实体属性名称和排序值向Criteria设置排序方式
*
* @param criteria Criteria设置排序方式,
* @param property orm实体属性名称
* @param dir 排序方法,"asc"或"desc"
*/
protected void setOrderToCriteria(Criteria criteria,String property,String dir) {
if(StringUtils.equals(dir.toLowerCase(), Sort.ASC)) {
criteria.addOrder(Order.asc(property));
} else {
criteria.addOrder(Order.desc(property));
}
}
/**
* 设置参数值到query的hql中,该参数是属于jpa风格的参数
*
* @param query Hibernate Query
* @param values 参数值可变数组
*/
protected void setQueryValuesByJpaStley(Query query ,Object... values) {
if (ArrayUtils.isEmpty(values)) {
return ;
}
for (Integer i = 1; i <= values.length; i++) {
query.setParameter(i.toString(), values[i - 1]);
}
}
/**
* 设置参数值到query的hql中,该参数是属于jdbc风格的参数
*
* @param query Hibernate Query
* @param values 参数值可变数组
*/
protected void setQueryValues(Query query ,Object... values) {
if (ArrayUtils.isEmpty(values)) {
return ;
}
for (Integer i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
}
/**
*
* 将对象集合执行转码操作
*
* @param source 要转码的对象集合
* @param executeMehtods 在什么方法进行转码
*/
protected void convertObjects(List<Object> source,ExecuteMehtod... executeMehtods) {
for (Iterator<Object> it = source.iterator(); it.hasNext();) {
convertObject(it.next(), executeMehtods);
}
}
/**
*
* 将对象执行转码操作
*
* @param source 要转码的对象
* @param executeMehtods 在什么方法进行转码
*/
protected void convertObject(Object source,ExecuteMehtod...executeMehtods) {
if (executeMehtods == null) {
return ;
}
ConvertCode convertCode = ReflectionUtils.getAnnotation(source.getClass(),ConvertCode.class);
if (convertCode == null) {
return ;
}
for (ExecuteMehtod em:executeMehtods) {
if (convertCode.executeMehtod().equals(em)) {
for (ConvertProperty convertProperty : convertCode.convertPropertys()) {
CodeStrategy strategy = ReflectionUtils.newInstance(convertProperty.strategyClass());
for (String property :convertProperty.propertyNames()) {
Object fromValue = ReflectionUtils.invokeGetterMethod(source, convertCode.fromProperty());
Object convertValue = strategy.convertCode(fromValue,property);
ReflectionUtils.invokeSetterMethod(source, property, convertValue);
}
}
}
}
}
/**
* 通过排序表达式向Criteria设置排序方式,
* @param criteria Criteria
* @param orderBy 排序表达式,规则为:属性名称_排序规则,如:property_asc或property_desc,可以支持多个属性排序,用逗号分割,如:"property1_asc,proerty2_desc",也可以"property"不加排序规则时默认是desc
*/
protected void setOrderToCriteria(Criteria criteria, String orderBy) {
if (StringUtils.isEmpty(orderBy)) {
return ;
}
String[] orderBys = null;
if (StringUtils.contains(orderBy,",")) {
orderBys = StringUtils.splitByWholeSeparator(orderBy, ",");
} else {
orderBys = new String[]{orderBy};
}
for (String ob: orderBys) {
if (StringUtils.contains(ob, "_")) {
String[] temp = StringUtils.splitByWholeSeparator(ob, "_");
String property = temp[0];
String dir = temp[1];
if (!StringUtils.equals(dir.toLowerCase(), Sort.ASC) && !StringUtils.equals(dir.toLowerCase(), Sort.DESC)) {
throw new IllegalAccessError("orderBy规则错误,当前为:" + dir + " 应该为:ASC或者:DESC");
}
setOrderToCriteria(criteria,property,dir);
} else {
setOrderToCriteria(criteria,ob,Sort.DESC);
}
}
}
/**
* 执行count查询获得本次Hql查询所能获得的对象总数.使用命名方式参数
*
* <pre>
* from object o where o.property = :proprty and o.property = :proprty
* </pre>
*
* 本函数只能自动处理简单的hql语句,复杂的hql查询请另行编写count语句查询.
*
* @param queryString HQL
* @param values 值
*
* @return long
*/
protected Long countHqlResult( String queryString, Map<String, ?> values) {
String countHql = prepareCountHql(queryString);
try {
return (Long)createQuery(queryString, values).uniqueResult();
} catch (Exception e) {
throw new RuntimeException("hql不能自动计算总是:"+ countHql, e);
}
}
/**
* 执行count查询获得本次Hql查询所能获得的对象总数.(使用jdbc方式参数)
*
* <pre>
* from object o where o.property = ? and o.property = ?
* </pre>
*
* 本函数只能自动处理简单的hql语句,复杂的hql查询请另行编写count语句查询.
*
* @param queryString HQL
* @param values 值
*
* @return long
*/
protected Long countHqlResult( String queryString, Object... values) {
String countHql = prepareCountHql(queryString);
try {
return (Long)createQuery(countHql, values).uniqueResult();
} catch (Exception e) {
throw new RuntimeException("hql不能自动计算总数:"+ countHql, e);
}
}
/**
* 执行count查询获得本次Hql查询所能获得的对象总数.(使用jpa风格参数)
*
* <pre>
* from object o where o.property = ?1 and o.property = ?2
* </pre>
*
* 本函数只能自动处理简单的hql语句,复杂的hql查询请另行编写count语句查询.
*
* @param queryString HQL
* @param values 值
*
* @return long
*/
protected Long countHqlResultUseJpaStyle( String queryString, Object... values) {
String countHql = prepareCountHql(queryString);
try {
return (Long)createQuery(countHql, values).uniqueResult();
} catch (Exception e) {
throw new RuntimeException("hql不能自动计算总数:"+ countHql, e);
}
}
/**
* 绑定计算总数HQL语句,返回绑定后的hql字符串
*
* @param orgHql hql
*
* @return String
*/
private String prepareCountHql(String orgHql) {
String countHql = "select count (*) " + removeSelect(removeOrders(orgHql));
return countHql;
}
/**
* 移除from前面的select 字段 返回移除后的hql字符串
* @param hql
* @return String
*/
private String removeSelect(String hql) {
int beginPos = hql.toLowerCase().indexOf("from");
return hql.substring(beginPos);
}
/**
* 删除hql中的 orderBy的字段,返回删除后的新字符串
*
* @param hql
*
* @return String
*/
private String removeOrders(String hql) {
Pattern p = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*",Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(hql);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, "");
}
m.appendTail(sb);
return sb.toString();
}
/**
* 为Query添加distinct transformer. 预加载关联对象的HQL会引起主对象重复, 需要进行distinct处理.
*
* @param query Hibernate Query 接口
*
* @return {@link Query};
*/
public Query distinct(Query query) {
query.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
return query;
}
/**
* 为Criteria添加distinct transformer. 预加载关联对象的HQL会引起主对象重复, 需要进行distinct处理.
*
* @param criteria Hibernate Criteria 接口
*
* @return {@link Criteria}
*/
public Criteria distinct(Criteria criteria) {
criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
return criteria;
}
/**
* 根据HQL创建迭代器
*
* @param queryString hql
* @param values 值
*
* @return Iterator
*/
public Iterator<T> iterator(String queryString,Object... values) {
Query query = createQuery(queryString, values);
return distinct(query).iterate();
}
/**
* 根据Criterion创建迭代器
*
* @param criterions 可变的Criterion参数
*
* @return Iterator
*/
public Iterator<T> iterator(Criterion...criterions) {
return distinct(createCriteria(criterions)).list().iterator();
}
/**
* 立即关闭迭代器而不是等待session.close的时候才关闭
* @param it 要关闭的迭代器
*
*/
public void closeIterator(Iterator<?> it) throws HibernateException {
Hibernate.close(it);
}
/**
* 将persistable对象 Object对象、代理对象、持久化对象,Collection 对象或为空的对象里的代理属性全部加载(该方法使用了Hibernate.initialize方法)
*
* @param proxy 一个persistable对象 Object对象、代理对象、持久化对象,Collection 对象或为空的对象
*
*/
public void initProxyObject(Object proxy) {
Hibernate.initialize(proxy);
}
/**
* Flush当前Session.
*/
public void flush() {
getSession().flush();
}
/**
* 如果session中存在相同持久化识别的实例,用给出的对象的状态覆盖持久化实例
*
* @param entity 持久化实例
*/
public void merge(T entity) {
if (!preproModifyEntity(entity)) {
return ;
}
getSession().merge(entity);
}
/**
* 如果session中存在相同持久化识别的实例,用给出的对象的状态覆盖持久化实例
*
* @param entity 持久化实例
* @param entityName 持久化对象名称
*/
public void merge(String entityName,T entity) {
if (!preproModifyEntity(entity)) {
return ;
}
getSession().merge(entityName, entity);
}
/**
* 刷新操作对象
*
* @param entity 操作对象
*/
public void refresh(T entity) {
if (!preproModifyEntity(entity)) {
return ;
}
getSession().refresh(entity);
}
/**
* 刷新操作对象
*
* @param entity 操作对象
* @param lockOptions Hibernate LockOptions
*/
public void refresh(T entity,LockOptions lockOptions) {
if (!preproModifyEntity(entity)) {
return ;
}
if (lockOptions == null) {
refresh(entity);
} else {
getSession().refresh(entity, lockOptions);
}
}
/**
* 把操作对象在缓存区中直接清除
*
* @param entity 操作对象
*/
public void evict(T entity) {
if (!preproModifyEntity(entity)) {
return ;
}
getSession().evict(entity);
}
/**
* 把session所有缓存区的对象全部清除,但不包括正在操作中的对象
*/
public void clear() {
getSession().clear();
}
/**
* 对于已经手动给ID主键的操作对象进行insert操作
*
* @param entity 操作对象
* @param replicationMode 创建策略
*/
public void replicate(T entity, ReplicationMode replicationMode) {
if (!preproModifyEntity(entity) || replicationMode == null) {
return ;
}
getSession().replicate(entity, replicationMode);
}
/**
* 对于已经手动给ID主键的操作对象进行insert操作
*
* @param entityName 操作对象名称
* @param entity 操作对象
* @param replicationMode 创建策略
*/
public void replicate(String entityName,T entity, ReplicationMode replicationMode) {
if (!preproModifyEntity(entity) || replicationMode == null) {
return ;
}
getSession().replicate(entityName,entity, replicationMode);
}
/**
* 把一个瞬态的实例持久化,但很有可能不能立即持久化实例,可能会在flush的时候才会持久化
* 当它在一个transaction外部被调用的时候并不会触发insert。
*
* @param entity 瞬态的实例
*/
public void persist(T entity) {
if (!preproModifyEntity(entity)) {
return ;
}
getSession().persist(entity);
}
/**
* 把一个瞬态的实例持久化,但很有可能不能立即持久化实例,可能会在flush的时候才会持久化
* 当它在一个transaction外部被调用的时候并不会触发insert。
*
* @param entity 瞬态的实例
* @param entityName 瞬态的实例名称
*/
public void persist(String entityName, T entity) {
if (!preproModifyEntity(entity)) {
return ;
}
getSession().persist(entityName,entity);
}
/**
* 从当前Session中获取一个能够操作JDBC的Connection并执行想要操作的JDBC语句
*
* @param work Hibernate Work
*/
public void doWork(Work work) {
getSession().doWork(work);
}
/**
* 判断entity实例是否已经与session缓存关联,是返回true,否则返回false
*
* @param entity 实例
*
* @return boolean
*/
public boolean contains(Object entity) {
return getSession().contains(entity);
}
/**
* 执行HQL进行批量修改/删除操作.成功后返回更新记录数,参数形式为命名参数形式:
* <pre>
* //使用的是命名参数风格
* update object o set o.property = :property where o.condition = :condition
* </pre>
*
* @param values 命名参数,按名称绑定.
*
* @return int
*/
public int executeUpdate(String hql, Map<String, ?> values) {
return createQuery(hql, values).executeUpdate();
}
/**
* 执行HQL进行批量修改/删除操作.成功后更新记录数,参数形式为jdbc参数形式:
* <pre>
* //使用是jdbc参数风格(问号后面没有带顺序值)
* update object o set o.property=? where o.condition = ?
* </pre>
*
* @param values 参数值
*
* @return int
*/
public int executeUpdate(String hql, Object... values) {
return createQuery(hql, values).executeUpdate();
}
/**
* 执行HQL进行批量修改/删除操作.成功后更新记录数,参数形式为jpa参数形式:
* <pre>
* //使用的是jpa参数风格(问号后面带有一个顺序值"?1")
* update object o set o.property=?1 where o.condition = ?2
* </pre>
*
* @param values 参数值
*
* @return int
*/
public int executeUpdateUseJpaStyle(String hql, Object...values) {
return createQueryUseJpaStyle(hql, values).executeUpdate();
}
/**
* 通过queryNamed执行HQL进行批量修改/删除操作.成功后返回更新记录数,参数形式为命名参数形式:
* <pre>
* //使用的是命名参数风格
* update object o set o.property = :property where o.condition = :condition
* </pre>
*
* @param values 命名参数,按名称绑定.
*
* @return int
*/
public int executeUpdateByQueryNamed(String queryNamed,Map<String, ?> values) {
return createQueryByQueryNamed(queryNamed, values).executeUpdate();
}
/**
* 通过queryNamed执行HQL进行批量修改/删除操作.成功后返回更新记录数,参数形式为jdbc参数形式:
* <pre>
* //使用是jdbc参数风格(问号后面没有带顺序值)
* update object o set o.property=? where o.condition = ?
* </pre>
*
* @param values 参数值
*
* @return int
*/
public int executeUpdateByQueryNamed(String queryNamed,Object... values) {
return createQueryByQueryNamed(queryNamed, values).executeUpdate();
}
/**
* 通过queryNamed执行HQL进行批量修改/删除操作.成功后返回更新记录数,参数形式为jpa参数形式:
* <pre>
* //使用的是jpa参数风格(问号后面带有一个顺序值"?1")
* update object o set o.property=?1 where o.condition = ?2
* </pre>
*
* @param values 参数值
*
* @return int
*/
public int executeUpdateByQueryNamedUseJapStyle(String queryNamed,Object... values) {
return createQueryByQueryNamedUseJpaStyle(queryNamed, values).executeUpdate();
}
}