hibernate功能擴展

package cn.infocare.propcare.orm.hibernate;java

import java.util.Collection; import java.util.List;spring

import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.springframework.orm.hibernate3.HibernateCallback;sql

import cn.infocare.propcare.PagingResult; import cn.infocare.propcare.SortConfig;express

/**session

  • 繼承自Spring的HibernateTemplate,提供一些附加功能,包括分頁查詢
  • @author jianglei

*/ public class HibernateTemplate extends org.springframework.orm.hibernate3.HibernateTemplate {hibernate

/**
 * 查詢惟一結果。在確認查詢結果惟一時使用,若結果有多個,則只會返回第一個結果
 * 
 * @param hql
 *            HQL表達式
 * @param params
 *            查詢參數
 * @return 惟一結果,結果爲空時返回null
 */
@SuppressWarnings("unchecked")
public Object findUnique(String hql, Object... params) {
    List result = find(hql, params);
    return result.size() == 0 ? null : result.get(0);
}

/**
 * 使用命名參數查詢惟一結果。在確認查詢結果惟一時使用,若結果有多個,則只會返回第一個結果
 * 
 * @param hql
 *            HQL表達式
 * @param paramNames
 *            查詢參數名稱清單
 * @param paramValues
 *            查詢參數值清單
 * @return 惟一結果,結果爲空時返回null
 */
@SuppressWarnings("unchecked")
public Object findUniqueByNamedParam(String hql, String[] paramNames,
        Object[] paramValues) {
    List result = findByNamedParam(hql, paramNames, paramValues);
    return result.size() == 0 ? null : result.get(0);
}

/**
 * 使用命名參數查詢惟一結果。在確認查詢結果惟一時使用,若結果有多個,則只會返回第一個結果
 * 
 * @param hql
 *            HQL表達式
 * @param paramNameList
 *            查詢參數名稱清單
 * @param paramValueList
 *            查詢參數值清單
 * @return 惟一結果,結果爲空時返回null
 */
public Object findUniqueByNamedParam(String hql,
        List<String> paramNameList, List<Object> paramValueList) {
    return findUniqueByNamedParam(hql,
            paramNameList.toArray(new String[0]),
            paramValueList.toArray(new Object[0]));
}

private String getTotalHql(String hql) {
    String s = " " + hql;
    int index = s.toLowerCase().indexOf(" from ");
    if (index >= 0) {
        String distinctSymbol = "select distinct ";
        int distinctSelectIndex = s.toLowerCase().indexOf(distinctSymbol);
        if (distinctSelectIndex < 0) {
            s = "select count(*) " + s.substring(index);
        } else {
            String entityName = s.substring(distinctSelectIndex
                    + distinctSymbol.length(), index);
            s = "select count(distinct " + entityName + ") "
                    + s.substring(index);
        }
        index = s.toLowerCase().indexOf(" order by ");
        int tailIndex = s.indexOf(")", index);
        if (index >= 0) { // 去掉原order by子句
            s = s.substring(0, index)
                    + (tailIndex >= 0 ? s.substring(tailIndex) : "");
        }
        return s;
    } else {
        throw new IllegalArgumentException("HQL '" + hql
                + "' cannot be used to paging query");
    }
}

private String getResultEntityAliasName(String hql) {
    String lowerHql = hql.toLowerCase();
    if (!lowerHql.startsWith("select ")) {
        return null;
    }
    if (lowerHql.contains("distinct")) {
        hql = hql.replaceFirst("distinct", "");
        lowerHql = hql.toLowerCase();
    }
    int index = lowerHql.indexOf(" from ");
    String temp = hql.substring("select ".length(), index);
    return temp.length() > 20 ? "" : temp;
}

private String joinHqlBySortConfig(String hql, SortConfig sortConfig) {
    if (sortConfig.isEmpty()) {
        return hql;
    }
    return hql + " order by "
            + sortConfig.toString(getResultEntityAliasName(hql));
}

/**
 * Execute an HQL query, binding a number of values to ":" named parameters
 * in the query string.
 * 
 * @param hql
 *            a query expressed in Hibernate's query language
 * @param paramNameList
 *            the name list of the parameters
 * @param paramValueList
 *            the value list of the parameters
 * @return a {@link List} containing the results of the query execution
 */
@SuppressWarnings("unchecked")
public List findByNamedParam(String hql, List<String> paramNameList,
        List<Object> paramValueList) {
    return findByNamedParam(hql, paramNameList.toArray(new String[0]),
            paramValueList.toArray(new Object[0]));
}

/**
 * 分頁查詢
 * 
 * @param hql
 *            HQL表達式
 * @param paramNames
 *            查詢參數名稱清單
 * @param paramValues
 *            查詢參數值清單
 * @param pageSize
 *            每頁記錄數,若<=0,則不進行實際分頁查詢,所有結果做爲一頁返回
 * @param pageNo
 *            頁碼,若<=0,則不進行實際分頁查詢,所有結果做爲一頁返回
 * @return 分頁查詢結果
 */
@SuppressWarnings("unchecked")
public PagingResult findByNamedParam(String hql, String[] paramNames,
        Object[] paramValues, int pageSize, int pageNo) {
    return findByNamedParam(hql, paramNames, paramValues, null, pageSize,
            pageNo);
}

/**
 * 分頁查詢
 * 
 * @param hql
 *            HQL表達式
 * @param paramNames
 *            查詢參數名稱清單
 * @param paramValues
 *            查詢參數值清單
 * @param pageSize
 *            每頁記錄數,若<=0,則不進行實際分頁查詢,所有結果做爲一頁返回
 * @param pageNo
 *            頁碼,若<=0,則不進行實際分頁查詢,所有結果做爲一頁返回
 * @return 分頁查詢結果
 */
@SuppressWarnings("unchecked")
public PagingResult findByNamedParam(String hql,
        List<String> paramNameList, List<Object> paramValueList,
        int pageSize, int pageNo) {
    return findByNamedParam(hql, paramNameList, paramValueList, null,
            pageSize, pageNo);
}

/**
 * 分頁查詢
 * 
 * @param hql
 *            HQL表達式
 * @param paramNames
 *            查詢參數名稱清單
 * @param paramValues
 *            查詢參數值清單
 * @param sortConfig
 *            排序設置
 * @param pageSize
 *            每頁記錄數,若<=0,則不進行實際分頁查詢,所有結果做爲一頁返回
 * @param pageNo
 *            頁碼,若<=0,則不進行實際分頁查詢,所有結果做爲一頁返回
 * @return 分頁查詢結果
 */
@SuppressWarnings("unchecked")
public PagingResult findByNamedParam(String hql, String[] paramNames,
        Object[] paramValues, SortConfig sortConfig, int pageSize,
        int pageNo) {
    return findByNamedParam(hql, paramNames, paramValues, sortConfig,
            pageSize, pageNo, true);
}

/**
 * 分頁查詢
 * 
 * @param hql
 *            HQL表達式
 * @param paramNames
 *            查詢參數名稱清單
 * @param paramValues
 *            查詢參數值清單
 * @param sortConfig
 *            排序設置
 * @param pageSize
 *            每頁記錄數,若<=0,則不進行實際分頁查詢,所有結果做爲一頁返回
 * @param pageNo
 *            頁碼,若<=0,則不進行實際分頁查詢,所有結果做爲一頁返回
 * @return 分頁查詢結果
 */
@SuppressWarnings("unchecked")
public PagingResult findByNamedParam(String hql,
        List<String> paramNameList, List<Object> paramValueList,
        SortConfig sortConfig, int pageSize, int pageNo) {
    return findByNamedParam(hql, paramNameList.toArray(new String[0]),
            paramValueList.toArray(new Object[0]), sortConfig, pageSize,
            pageNo);
}

/**
 * 分頁查詢
 * 
 * @param hql
 *            HQL表達式
 * @param paramNames
 *            查詢參數名稱
 * @param paramValues
 *            查詢參數值
 * @param pageSize
 *            每頁記錄數,若<=0,則不進行實際分頁查詢,所有結果做爲一頁返回
 * @param pageNo
 *            頁碼,若<=0,則不進行實際分頁查詢,所有結果做爲一頁返回
 * @param findTotal
 *            是否查詢記錄總條數
 * @return 分頁查詢結果
 */
@SuppressWarnings("unchecked")
public PagingResult findByNamedParam(String hql, String[] paramNames,
        Object[] paramValues, int pageSize, int pageNo, boolean findTotal) {
    return findByNamedParam(hql, paramNames, paramValues, null, pageSize,
            pageNo, findTotal);
}

/**
 * 分頁查詢
 * 
 * @param hql
 *            HQL表達式
 * @param paramNames
 *            查詢參數名稱
 * @param paramValues
 *            查詢參數值
 * @param sortConfig
 *            排序設置
 * @param pageSize
 *            每頁記錄數,若<=0,則不進行實際分頁查詢,所有結果做爲一頁返回
 * @param pageNo
 *            頁碼,若<=0,則不進行實際分頁查詢,所有結果做爲一頁返回
 * @param findTotal
 *            是否查詢記錄總條數
 * @return 分頁查詢結果
 */
@SuppressWarnings("unchecked")
private PagingResult findByNamedParam(final String hql,
        final String[] paramNames, final Object[] paramValues,
        SortConfig sortConfig, final int pageSize, final int pageNo,
        boolean findTotal) {
    if (sortConfig == null) {
        sortConfig = new SortConfig();
    }
    if (hql.toLowerCase().indexOf(" order by ") >= 0
            && !sortConfig.isEmpty()) {
        throw new HibernateException(
                "The hql that contains 'order by' can not use the SortConfig");
    }

    // 查詢總數
    Long total = 0l;
    if (findTotal) {
        total = executeWithNativeSession(new HibernateCallback<Long>() {
            public Long doInHibernate(Session session)
                    throws HibernateException {
                Query query = session.createQuery(getTotalHql(hql));
                setQueryParams(query, paramNames, paramValues);
                return (Long) query.uniqueResult();
            }
        });
    }
    // 查詢結果
    final String queryString = joinHqlBySortConfig(hql, sortConfig);
    List<Object> records = executeWithNativeSession(new HibernateCallback<List>() {
        public List doInHibernate(Session session)
                throws HibernateException {
            Query queryObject = session.createQuery(queryString);
            // 每頁記錄數或頁碼小於等於0,則不進行實際分頁查詢,將結果做爲一頁返回
            if (pageSize > 0 && pageNo > 0) {
                queryObject.setFirstResult(pageSize * (pageNo - 1));
                queryObject.setMaxResults(pageSize);
            }
            prepareQuery(queryObject);
            setQueryParams(queryObject, paramNames, paramValues);
            return queryObject.list();
        }
    });
    return new PagingResult<Object>(records, total.intValue(), pageSize,
            pageNo);
}

@SuppressWarnings("unchecked")
private void setQueryParams(Query query, String[] paramNames,
        Object[] paramValues) {
    for (int i = 0; i < paramNames.length; i++) {
        if (paramValues[i] instanceof Collection) {
            query.setParameterList(paramNames[i],
                    (Collection) paramValues[i]);
        } else if (paramValues[i] instanceof Object[]) {
            Object[] paramValue = (Object[]) paramValues[i];
            query.setParameterList(paramNames[i], paramValue);
        } else {
            query.setParameter(paramNames[i], paramValues[i]);
        }
    }
}

/**
 * 查詢記錄數,以命名參數的查詢語句形式。
 * 
 * @param hql
 *            HQL語句
 * @param paramNames
 *            查詢參數名稱清單
 * @param paramValues
 *            查詢參數值清單
 * @return 記錄數
 */
public long countByNamedParam(final String hql, final String[] paramNames,
        final Object[] paramValues) {
    return executeWithNativeSession(new HibernateCallback<Long>() {
        public Long doInHibernate(Session session)
                throws HibernateException {
            Query query = session.createQuery(getTotalHql(hql));
            setQueryParams(query, paramNames, paramValues);
            return (Long) query.uniqueResult();
        }
    });
}

/**
 * 查詢記錄數,以命名參數的查詢語句形式。
 * 
 * @param hql
 *            HQL語句
 * @param paramNames
 *            查詢參數名稱清單
 * @param paramValues
 *            查詢參數值清單
 * @return 記錄數
 */
public long countByNamedParam(String hql, List<String> paramNameList,
        List<Object> paramValueList) {
    return countByNamedParam(hql, paramNameList.toArray(new String[0]),
            paramValueList.toArray(new Object[0]));
}

/**
 * 查詢記錄數,以順序參數的查詢語句形式。
 * 
 * @param hql
 *            HQL語句
 * @param params
 *            查詢參數
 * @return 記錄數
 */
public long count(final String hql, final Object... params) {
    return executeWithNativeSession(new HibernateCallback<Long>() {
        public Long doInHibernate(Session session)
                throws HibernateException {
            Query query = session.createQuery(getTotalHql(hql));
            for (int i = 0; i < params.length; i++) {
                query.setParameter(i, params[i]);
            }
            return (Long) query.uniqueResult();
        }
    });
}

/**
 * 根據排序設置查詢記錄,以命名參數的查詢語句形式。
 * 
 * @param hql
 *            HQL語句
 * @param paramNames
 *            查詢參數名稱清單
 * @param paramValues
 *            查詢參數值清單
 * @param sortConfig
 *            排序設置
 * @return 查詢結果記錄
 */
@SuppressWarnings("unchecked")
public List findByNamedParam(String hql, String[] paramNames,
        Object[] paramValues, SortConfig sortConfig) {
    if (sortConfig == null) {
        sortConfig = new SortConfig();
    }
    if (hql.toLowerCase().indexOf(" order by ") >= 0
            && !sortConfig.isEmpty()) {
        throw new HibernateException(
                "The hql that contains 'order by' can not use the SortConfig");
    }
    if (paramNames == null) {
        paramNames = new String[0];
    }
    if (paramValues == null) {
        paramValues = new Object[0];
    }
    hql = joinHqlBySortConfig(hql, sortConfig);
    return findByNamedParam(hql, paramNames, paramValues);
}

/**
 * Update/delete all objects according to the given query, binding a number
 * of values to ":" named parameters in the update string.
 * 
 * @param hql
 *            an update/delete query expressed in Hibernate's query language
 * @param paramNames
 *            the names of the parameters
 * @param paramValues
 *            the values of the parameters
 * @return the number of instances updated/deleted
 */
public int bulkUpdateByNamedParam(final String hql,
        final String[] paramNames, final Object[] paramValues) {
    return executeWithNativeSession(new HibernateCallback<Integer>() {
        public Integer doInHibernate(Session session)
                throws HibernateException {
            Query queryObject = session.createQuery(hql);
            prepareQuery(queryObject);
            if (paramNames != null && paramValues != null) {
                for (int i = 0; i < paramValues.length; i++) {
                    String name = paramNames[i];
                    Object value = paramValues[i];
                    if (value instanceof Object[]) {
                        queryObject
                                .setParameterList(name, (Object[]) value);
                    } else if (value instanceof Collection<?>) {
                        queryObject.setParameterList(name,
                                (Collection<?>) value);
                    } else {
                        queryObject.setParameter(name, value);
                    }
                }
            }
            return queryObject.executeUpdate();
        }
    });
}

public int bulkUpdateBySqlAndNamedParam(final String sql,
        final String[] paramNames, final Object[] paramValues) {
    return executeWithNativeSession(new HibernateCallback<Integer>() {
        public Integer doInHibernate(Session session)
                throws HibernateException {
            Query queryObject = session.createSQLQuery(sql);
            prepareQuery(queryObject);
            if (paramNames != null && paramValues != null) {
                for (int i = 0; i < paramValues.length; i++) {
                    String name = paramNames[i];
                    Object value = paramValues[i];
                    if (value instanceof Object[]) {
                        queryObject
                                .setParameterList(name, (Object[]) value);
                    } else if (value instanceof Collection<?>) {
                        queryObject.setParameterList(name,
                                (Collection<?>) value);
                    } else {
                        queryObject.setParameter(name, value);
                    }
                }
            }
            return queryObject.executeUpdate();
        }
    });
}

/**
 * Update/delete all objects according to the given query, binding a number
 * of values to ":" named parameters in the update string.
 * 
 * @param hql
 *            an update/delete query expressed in Hibernate's query language
 * @param paramNameList
 *            the name list of the parameters
 * @param paramValueList
 *            the value list of the parameters
 * @return the number of instances updated/deleted
 */
public int bulkUpdateByNamedParam(String hql, List<String> paramNameList,
        List<Object> paramValueList) {
    return bulkUpdateByNamedParam(hql,
            paramNameList.toArray(new String[0]),
            paramValueList.toArray(new Object[0]));
}

public int bulkUpdateBySqlAndNamedParam(String hql,
        List<String> paramNameList, List<Object> paramValueList) {
    return bulkUpdateBySqlAndNamedParam(hql,
            paramNameList.toArray(new String[0]),
            paramValueList.toArray(new Object[0]));
}

public List<Object[]> findBySqlAndNamedParam(final String sql,
        final String[] paramNames, final Object[] paramValues) {
    return executeWithNativeSession(new HibernateCallback<List<Object[]>>() {
        public List<Object[]> doInHibernate(Session session)
                throws HibernateException {
            Query queryObject = session.createSQLQuery(sql);
            prepareQuery(queryObject);
            setQueryParams(queryObject, paramNames, paramValues);
            return queryObject.list();
        }
    });
}

public List<Object[]> findBySqlAndNamedParam(final String sql,
        final String[] paramNames, final Object[] paramValues,
        final int pageSize, final int pageNo) {
    return executeWithNativeSession(new HibernateCallback<List<Object[]>>() {
        public List<Object[]> doInHibernate(Session session)
                throws HibernateException {
            Query queryObject = session.createSQLQuery(sql);
            // 每頁記錄數或頁碼小於等於0,則不進行實際分頁查詢,將結果做爲一頁返回
            if (pageSize > 0 && pageNo > 0) {
                queryObject.setFirstResult(pageSize * (pageNo - 1));
                queryObject.setMaxResults(pageSize);
            }
            prepareQuery(queryObject);
            setQueryParams(queryObject, paramNames, paramValues);
            return queryObject.list();
        }
    });
}

public List<Object[]> findBySqlAndNamedParam(String sql,
        List<String> paramNameList, List<Object> paramValueList) {
    return findBySqlAndNamedParam(sql,
            paramNameList.toArray(new String[0]),
            paramValueList.toArray(new Object[0]));
}

public List<Object[]> findBySqlAndNamedParam(String sql,
        List<String> paramNameList, List<Object> paramValueList,
        int pageSize, int pageNo) {
    return findBySqlAndNamedParam(sql,
            paramNameList.toArray(new String[0]),
            paramValueList.toArray(new Object[0]), pageSize, pageNo);
}

}code

相關文章
相關標籤/搜索