/**
 * 
 */
package com.hbasesoft.framework.db.hibernate;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.collections.MapUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.internal.CriteriaImpl;
import org.hibernate.jdbc.Work;
import org.hibernate.transform.ResultTransformer;
import org.hibernate.transform.Transformers;

import com.hbasesoft.framework.common.ErrorCodeDef;
import com.hbasesoft.framework.common.GlobalConstants;
import com.hbasesoft.framework.common.utils.Assert;
import com.hbasesoft.framework.common.utils.UtilException;
import com.hbasesoft.framework.common.utils.logger.Logger;
import com.hbasesoft.framework.db.TransactionManagerHolder;
import com.hbasesoft.framework.db.core.DaoException;
import com.hbasesoft.framework.db.core.config.DataParam;
import com.hbasesoft.framework.db.core.executor.ISqlExcutor;
import com.hbasesoft.framework.db.core.utils.PagerList;
import com.hbasesoft.framework.db.core.utils.SQlCheckUtil;

/**
 * <Description> <br>
 * 
 * @author 伟<br>
 * @version 1.0<br>
 * @CreateDate 2014-10-26 <br>
 * @see com.hbasesoft.framework.dao.support.hibernate <br>
 */
@SuppressWarnings({
    "rawtypes", "deprecation", "unchecked"
})
public class BaseHibernateDao implements IGenericBaseDao, ISqlExcutor {

    /** Number */
    private static final int NUM_100 = 100;

    /**
     * logger
     */
    private static Logger logger = new Logger(BaseHibernateDao.class);

    /** entity class */
    private Class<?> entityClazz;

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param sql
     * @param param
     * @return
     * @throws DaoException <br>
     */
    @Override
    public Object query(final String sql, final DataParam param) throws DaoException {
        try {

            SQlCheckUtil.checkSql(sql);

            Session session = getSession();
            session.flush();

            SQLQuery query = session.createSQLQuery(sql);

            // Redis缓存序列化时不能有void返回类型,特殊处理一下
            if (param.getReturnType() == null) {
                param.setReturnType(void.class);
            }

            // step1:设置参数
            setParamMap(param.getParamMap(), query);

            // step2:设置返回值类型
            final Object callBack = param.getCallback();
            if (callBack != null && callBack instanceof ResultTransformer) {
                query.setResultTransformer((ResultTransformer) callBack);
            }
            else if (param.getBeanType().equals(Map.class)) {
                query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
            }
            else {
                Class<?> beanType = param.getBeanType();
                if (Serializable.class.equals(beanType)) {
                    beanType = param.getReturnType();
                    if (entityClazz != null && List.class.isAssignableFrom(param.getReturnType())) {
                        beanType = entityClazz;
                    }
                }
                query.setResultTransformer(new AutoResultTransformer(beanType));
            }

            boolean isPager = false;
            PagerList resultList = null;

            if (param.getPageIndex() == 0) {
                param.setPageIndex(1);
            }

            // step3:设置分页
            if (param.getPageIndex() != -1 && param.getPageSize() != -1
                && List.class.isAssignableFrom(param.getReturnType())) {
                query.setFirstResult((param.getPageIndex() - 1) * param.getPageSize());
                query.setMaxResults(param.getPageSize());

                SQLQuery countQuery = session.createSQLQuery("SELECT COUNT(1) FROM (" + sql + ") QUERY_DATA__");
                setParamMap(param.getParamMap(), countQuery);
                resultList = new PagerList();
                resultList.setPageIndex(param.getPageIndex());
                resultList.setPageSize(param.getPageSize());
                resultList.setTotalCount(Long.valueOf(countQuery.uniqueResult().toString()));
                isPager = true;
            }

            if (isPager) {
                if (resultList.getTotalCount() > 0
                    && (resultList.getPageIndex() - 1) * resultList.getPageSize() < resultList.getTotalCount()) {
                    resultList.addAll(query.list());
                }
                return resultList;
            }
            else if (List.class.isAssignableFrom(param.getReturnType())) {
                return query.list();
            }
            else {
                return query.uniqueResult();
            }
        }
        catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new DaoException(ErrorCodeDef.QUERY_ERROR_10010, e);
        }
    }

    /**
     * Description: <br>
     * 
     * @author yang.zhipeng <br>
     * @taskId <br>
     * @param paramMap <br>
     * @param query <br>
     * @throws DaoException <br>
     */
    private void setParamMap(final Map<String, Object> paramMap, final Query query) throws DaoException {
        if (MapUtils.isNotEmpty(paramMap)) {
            for (Entry<String, Object> entry : paramMap.entrySet()) {
                Object obj = entry.getValue();

                // 这里考虑传入的参数是什么类型,不同类型使用的方法不同
                if (obj instanceof Collection<?>) {
                    query.setParameterList(entry.getKey(), (Collection<?>) obj);
                }
                else if (obj != null && obj.getClass().isArray() && obj instanceof Object[]) {
                    query.setParameterList(entry.getKey(), (Object[]) obj);
                }
                else {
                    query.setParameter(entry.getKey(), obj);
                }
            }
        }

    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param sql
     * @param param
     * @return
     * @throws DaoException <br>
     */
    @Override
    public int excuteSql(final String sql, final DataParam param) throws DaoException {
        try {
            SQlCheckUtil.checkSql(sql);
            Session session = getSession();
            session.flush();

            SQLQuery query = session.createSQLQuery(sql);
            setParamMap(param.getParamMap(), query);
            return query.executeUpdate();
        }
        catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new DaoException(ErrorCodeDef.EXECUTE_ERROR_10011, e);
        }
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param sqls
     * @param param
     * @return
     * @throws DaoException <br>
     */
    @Override
    public int[] batchExcuteSql(final String[] sqls, final DataParam param) throws DaoException {
        try {
            Session session = getSession();
            session.flush();

            int[] result = new int[sqls.length];
            SQLQuery query;
            for (int i = 0; i < sqls.length; i++) {
                query = session.createSQLQuery(sqls[i]);
                setParamMap(param.getParamMap(), query);
                result[i] = query.executeUpdate();
            }
            return result;
        }
        catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new DaoException(ErrorCodeDef.BATCH_EXECUTE_ERROR_10012, e);
        }
    }

    /**
     * 创建Criteria对象带属性比较
     *
     * @param <T>
     * @param entityClass
     * @param criterions
     * @return Criteria
     */
    private <T> Criteria createCriteria(final Class<T> entityClass, final Criterion... criterions) {
        Criteria criteria = getSession().createCriteria(entityClass);
        for (Criterion c : criterions) {
            criteria.add(c);
        }
        return criteria;
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @return <br>
     */
    protected Session getSession() {
        // 事务必须是开启的(Required),否则获取不到
        return TransactionManagerHolder.getSessionFactory().getCurrentSession();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param entity
     * @return
     * @throws DaoException <br>
     */
    @Override
    public <T> Serializable save(final T entity) throws DaoException {
        try {
            Serializable id = getSession().save(entity);
            logger.debug("保存实体成功," + entity.getClass().getName());
            return id;
        }
        catch (Exception e) {
            logger.error("保存实体异常", e);
            throw new DaoException(ErrorCodeDef.SAVE_ERROR_10013, e);
        }
    }

    /**
     * 根据传入的实体添加或更新对象
     *
     * @param <T>
     * @param entity
     */
    @Override
    public <T> void saveOrUpdate(final T entity) throws DaoException {
        try {
            getSession().saveOrUpdate(entity);
            logger.debug("添加或更新成功," + entity.getClass().getName());
        }
        catch (RuntimeException e) {
            logger.error("添加或更新异常", e);
            throw new DaoException(ErrorCodeDef.SAVE_ERROR_10013, e);
        }
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param entity
     * @throws DaoException <br>
     */
    @Override
    public <T> void delete(final T entity) throws DaoException {
        try {
            getSession().delete(entity);
            logger.debug("删除成功," + entity.getClass().getName());
        }
        catch (RuntimeException e) {
            logger.error("删除异常", e);
            throw e;
        }
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param entitys
     * @throws DaoException <br>
     */
    @Override
    public <T> void batchSave(final List<T> entitys) throws DaoException {
        if (entitys.size() > GlobalConstants.DEFAULT_LINES) {
            throw new UtilException(ErrorCodeDef.TOO_MANY_OBJECTS);
        }
        for (int i = 0; i < entitys.size(); i++) {
            getSession().save(entitys.get(i));
            if (i % NUM_100 == 0) {
                // 1000个对象后才清理缓存,写入数据库
                getSession().flush();
                getSession().clear();
            }
        }
        // 最后清理一下----防止大于1000小于2000的不保存
        getSession().flush();
        getSession().clear();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param entityClass
     * @param id
     * @param <T> T
     * @return T
     * @throws DaoException <br>
     */
    @Override
    public <T> T get(final Class<T> entityClass, final Serializable id) throws DaoException {
        Assert.notNull(id, ErrorCodeDef.ID_IS_NULL);
        return (T) getSession().get(entityClass, id);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param entityName
     * @param id
     * @return
     * @throws DaoException <br>
     */
    @Override
    public <T> T getEntity(final Class<T> entityName, final Serializable id) throws DaoException {
        return get(entityName, id);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param entityClass
     * @param propertyName
     * @param value
     * @return
     * @throws DaoException <br>
     */

    @Override
    public <T> T findUniqueByProperty(final Class<T> entityClass, final String propertyName, final Object value)
        throws DaoException {
        Assert.notEmpty(propertyName, ErrorCodeDef.DAO_PROPERTY_IS_EMPTY);
        return (T) createCriteria(entityClass, Restrictions.eq(propertyName, value)).uniqueResult();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param entityClass
     * @param propertyName
     * @param value
     * @return
     * @throws DaoException <br>
     */

    @Override
    public <T> List<T> findByProperty(final Class<T> entityClass, final String propertyName, final Object value)
        throws DaoException {
        Assert.notEmpty(propertyName, ErrorCodeDef.DAO_PROPERTY_IS_EMPTY);
        return (List<T>) createCriteria(entityClass, Restrictions.eq(propertyName, value)).list();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param entityClass
     * @return
     * @throws DaoException <br>
     */

    @Override
    public <T> List<T> loadAll(final Class<T> entityClass) throws DaoException {
        return createCriteria(entityClass).list();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param entityName
     * @param id
     * @throws DaoException <br>
     */
    @Override
    public <T> void deleteEntityById(final Class<T> entityName, final Serializable id) throws DaoException {
        Assert.notNull(id, ErrorCodeDef.ID_IS_NULL);
        T entity = get(entityName, id);
        if (entity != null) {
            delete(entity);
        }
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param entities
     * @throws DaoException <br>
     */
    @Override
    public <T> void deleteAllEntitie(final Collection<T> entities) throws DaoException {
        for (Object entity : entities) {
            getSession().delete(entity);
        }
        getSession().flush();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param ids
     * @throws DaoException <br>
     */
    @Override
    public <T> void deleteAllEntitiesByIds(final Class<T> entityName, final Collection<? extends Serializable> ids)
        throws DaoException {
        Assert.notEmpty(ids, ErrorCodeDef.ID_IS_NULL);
        for (Serializable id : ids) {
            getSession().delete(get(entityName, id));
        }
        getSession().flush();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param pojo
     * @throws DaoException <br>
     */
    @Override
    public <T> void updateEntity(final T pojo) throws DaoException {
        getSession().update(pojo);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param hql
     * @return
     * @throws DaoException <br>
     */

    @Override
    public <T> List<T> findByQueryString(final String hql) throws DaoException {
        Query queryObject = getSession().createQuery(hql);
        return queryObject.list();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param sql
     * @return
     * @throws DaoException <br>
     */
    @Override
    public int updateBySqlString(final String sql) throws DaoException {
        Session session = getSession();
        session.flush();

        Query querys = session.createSQLQuery(sql);
        return querys.executeUpdate();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param sql
     * @param <T> T
     * @return T
     * @throws DaoException <br>
     */

    @Override
    public <T> List<T> findListbySql(final String sql) throws DaoException {
        Session session = getSession();
        session.flush();
        Query querys = session.createSQLQuery(sql);
        return querys.list();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param hql
     * @return
     * @throws DaoException <br>
     */

    @Override
    public <T> T singleResult(final String hql) throws DaoException {
        return (T) getSession().createQuery(hql).uniqueResult();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param detachedCriteria
     * @param pi
     * @param pageSize
     * @param <T> T
     * @return T
     * @throws DaoException <br>
     */
    @Override
    public <T> PagerList<T> getPageList(final DetachedCriteria detachedCriteria, final int pi, final int pageSize)
        throws DaoException {
        int pageIndex = pi;
        if (pi == 0) {
            pageIndex = 1;
        }

        Criteria criteria = detachedCriteria.getExecutableCriteria(getSession());

        // 查询分页总数
        CriteriaImpl impl = (CriteriaImpl) criteria;
        Projection projection = impl.getProjection();
        Long allCounts = (Long) criteria.setProjection(Projections.rowCount()).uniqueResult();

        criteria.setProjection(projection);
        criteria.setFirstResult((pageIndex - 1) * pageSize);
        criteria.setMaxResults(pageSize);

        PagerList<T> resultList = new PagerList<T>();
        resultList.setPageIndex(pageIndex);
        resultList.setPageSize(pageSize);
        if (allCounts == null) {
            allCounts = 0L;
        }
        resultList.setTotalCount(allCounts);

        if (allCounts > 0) {
            resultList.addAll(criteria.list());
        }
        return resultList;
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param detachedCriteria
     * @param <T> T
     * @return T
     * @throws DaoException <br>
     */
    @Override
    public <T> List<T> getListByCriteriaQuery(final DetachedCriteria detachedCriteria) throws DaoException {
        return detachedCriteria.getExecutableCriteria(getSession()).list();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param hql
     * @param param
     * @return
     * @throws DaoException <br>
     */

    @Override
    public <T> List<T> findHql(final String hql, final Object... param) throws DaoException {
        Query q = getSession().createQuery(hql);
        if (param != null && param.length > 0) {
            for (int i = 0; i < param.length; i++) {
                q.setParameter(i, param[i]);
            }
        }
        return q.list();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param procedureSql
     * @param params
     * @return
     * @throws DaoException <br>
     */

    @Override
    public <T> List<T> executeProcedure(final String procedureSql, final Object... params) throws DaoException {
        Session session = getSession();
        session.flush();
        SQLQuery sqlQuery = session.createSQLQuery(procedureSql);

        for (int i = 0; i < params.length; i++) {
            sqlQuery.setParameter(i, params[i]);
        }
        return sqlQuery.list();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param detachedCriteria
     * @return
     * @throws DaoException <br>
     */

    @Override
    public <T> T getCriteriaQuery(final DetachedCriteria detachedCriteria) throws DaoException {
        return (T) detachedCriteria.getExecutableCriteria(getSession()).uniqueResult();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param sql
     * @param objcts
     * @param commitNumber
     * @throws DaoException <br>
     */
    @Override
    public <T> void batchExecute(final String sql, final Collection<Object[]> objcts, final int commitNumber)
        throws DaoException {
        Session session = getSession();
        session.flush();

        session.doWork(new Work() {

            @Override
            public void execute(final Connection connection) throws SQLException {
                PreparedStatement stmt = null;
                try {
                    stmt = connection.prepareStatement(sql);
                    connection.setAutoCommit(false);
                    int i = 0;
                    for (Object[] object : objcts) {
                        i++;
                        for (int j = 0; j < object.length; j++) {
                            stmt.setObject(j + 1, object[j]);
                        }
                        stmt.addBatch();
                        if (i % commitNumber == 0) {
                            stmt.executeBatch();
                            connection.commit();
                        }
                    }
                    stmt.executeBatch();
                    connection.commit();
                }
                finally {
                    if (stmt != null) {
                        stmt.close();
                    }
                }
            }
        });
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     *         <br>
     */
    @Override
    public void clear() {
        try {
            getSession().clear();
        }
        catch (Exception e) {
            throw new DaoException(e);
        }
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     *         <br>
     */
    @Override
    public void flush() {
        try {
            getSession().flush();
        }
        catch (Exception e) {
            throw new DaoException(e);
        }
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param entitys <br>
     * @param <T> T
     */
    public <T> void saveBatch(final List<T> entitys) {
        this.batchSave(entitys);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param entitys <br>
     * @param <T> T
     */
    public <T> void updateBatch(final List<T> entitys) {
        if (entitys.size() > GlobalConstants.DEFAULT_LINES) {
            throw new UtilException(ErrorCodeDef.TOO_MANY_OBJECTS);
        }
        for (int i = 0; i < entitys.size(); i++) {
            getSession().update(entitys.get(i));
            if (i % NUM_100 == 0) {
                // 1000个对象后才清理缓存,写入数据库
                getSession().flush();
                getSession().clear();
            }
        }
        // 最后清理一下----防止大于1000小于2000的不保存
        getSession().flush();
        getSession().clear();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param pojo <br>
     * @param <T> T
     */
    public <T> void update(final T pojo) {
        this.updateEntity(pojo);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param sql
     * @return <br>
     */
    public int updateBySql(final String sql) {
        return this.updateBySqlString(sql);
    };

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param id <br>
     */
    public void deleteById(final Serializable id) {
        this.deleteEntityById(getEntityClazz(), id);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param entities <br>
     * @param <T> T
     */
    public <T> void delete(final Collection<T> entities) {
        this.deleteAllEntitie(entities);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param ids <br>
     */
    public void deleteByIds(final Collection<? extends Serializable> ids) {
        this.deleteAllEntitiesByIds(getEntityClazz(), ids);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param id
     * @param <T> T
     * @return <br>
     */
    public <T> T get(final Serializable id) {
        return (T) this.get(getEntityClazz(), id);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param propertyName
     * @param value
     * @param <T> T
     * @return <br>
     */
    public <T> T getByProperty(final String propertyName, final Object value) {
        return (T) this.findUniqueByProperty(getEntityClazz(), propertyName, value);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param detachedCriteria
     * @param <T> T
     * @return <br>
     */
    public <T> T getByCriteria(final DetachedCriteria detachedCriteria) {
        return this.getCriteriaQuery(detachedCriteria);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param hql
     * @param <T> T
     * @return <br>
     */
    public <T> T getByHql(final String hql) {
        return this.singleResult(hql);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param <T> T
     * @return <br>
     */
    public <T> List<T> queryAll() {
        return (List<T>) this.loadAll(getEntityClazz());
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param propertyName
     * @param value
     * @param <T> T
     * @return <br>
     */
    public <T> List<T> queryByProperty(final String propertyName, final Object value) {
        return (List<T>) this.findByProperty(getEntityClazz(), propertyName, value);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param detachedCriteria
     * @param pageIndex
     * @param pageSize
     * @param <T> T
     * @return <br>
     */
    public <T> PagerList<T> queryPagerByCriteria(final DetachedCriteria detachedCriteria, final int pageIndex,
        final int pageSize) {
        return this.getPageList(detachedCriteria, pageIndex, pageSize);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param detachedCriteria
     * @param <T> T
     * @return <br>
     */
    public <T> List<T> queryByCriteria(final DetachedCriteria detachedCriteria) {
        return this.getListByCriteriaQuery(detachedCriteria);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param sql
     * @param <T> T
     * @return <br>
     */
    public <T> List<T> queryBySql(final String sql) {

        Session session = getSession();
        session.flush();
        Query query = session.createSQLQuery(sql);

        if (getEntityClazz().equals(Map.class)) {
            query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        }
        else {
            query.setResultTransformer(new AutoResultTransformer(getEntityClazz()));
        }
        return query.list();
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param hql
     * @param param
     * @param <T> T
     * @return <br>
     */
    public <T> List<T> queryByHqlParam(final String hql, final Object... param) {
        return findHql(hql, param);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param hql
     * @param <T> T
     * @return <br>
     */
    public <T> List<T> queryByHql(final String hql) {
        return this.findByQueryString(hql);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param sql
     * @param objcts
     * @param commitNumber <br>
     */
    public void executeBatch(final String sql, final Collection<Object[]> objcts, final int commitNumber) {
        this.batchExecute(sql, objcts, commitNumber);
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @return <br>
     */
    private Class<?> getEntityClazz() {
        Assert.notNull(entityClazz, ErrorCodeDef.PROXY_TARGET_NOT_FOUND);
        return entityClazz;
    }

    /**
     * Description: <br>
     * 
     * @author 王伟<br>
     * @taskId <br>
     * @param entityClazz <br>
     */
    public void setEntityClazz(final Class<?> entityClazz) {
        this.entityClazz = entityClazz;
    }

}