Разбивка на страницы с помощью функции findByNamedParam в HibernateTemplate - PullRequest
3 голосов
/ 25 февраля 2011

Я видел много примеров того, как создать нумерацию страниц с некоторыми действительно простыми запросами. Но я не вижу ни одного, использующего метод findByNamedParam из HibernateTemplate.

Как установить параметры запроса firstResult и maxResult, одновременно используя метод findByNamedParam?

В основном я пытаюсь добавить нумерацию страниц в запрос hql, который создаю с помощью метода findByNamedParam в HibernateTemplate.

Ответы [ 2 ]

5 голосов
/ 25 февраля 2011

Хорошо, после долгих исследований, я наконец-то получил то, что хотел.

Сначала нужно создать реализацию HibernateCallback:

HibernateCallbackImpl.java:

import java.sql.SQLException;
import java.util.List;

import org.apache.poi.hssf.record.formula.functions.T;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;

public class HibernateCallbackImpl 
    implements HibernateCallback<List<T>> {

    private String queryString;
    private String[] paramNames;
    private Object[] values;

    private int firstResult;
    private int maxResults;

    /**
     * Fetches a {@link List} of entities from the database using pagination.
     * Execute HQL query, binding a number of values to ":" named parameters in the query string.
     * 
     * @param queryString a query expressed in Hibernate's query language
     * @param paramNames the names of the parameters
     * @param values the values of the parameters 
     * @param firstResult a row number, numbered from 0
     * @param maxResults the maximum number of rows
     */
    public HibernateCallbackImpl(
            String queryString, 
            String[] paramNames, 
            Object[] values,
            int firstResult,
            int maxResults) {
        this.queryString = queryString;
        this.paramNames = paramNames;
        this.values = values;

        this.firstResult = firstResult;
        this.maxResults = maxResults;
    }

    @Override
    public List<T> doInHibernate(Session session) throws HibernateException,
            SQLException {
        Query query = session.createQuery(queryString);
        query.setFirstResult(firstResult);
        query.setMaxResults(maxResults);

        // TODO: throw proper exception when paramNames.length != values.length

        for (int c=0; c<paramNames.length; c++) {
            query.setParameter(paramNames[c], values[c]);
        }

        @SuppressWarnings("unchecked")
        List<T> result = query.list();

        return result;
    }

}

Затем я могу просто создать новый объект, и он вернет то, что я хочу:

Пример:

@SuppressWarnings("unchecked")
List<TitleProductAccountApproval> tpaas = 
    getHibernateTemplate().executeFind(
        new HibernateCallbackImpl(
            hql.toString(), 
            paramNames.toArray(new String[paramNames.size()]), 
            values.toArray(),
            firstResult,
            maxResult
        )
    );
4 голосов
/ 08 июня 2012

Решение @Corey прекрасно работает, но оно содержит проблему внутри цикла for, где вызывается query.setParameter (...).

Проблема заключается в том, что он не учитывает параметры, которые являются либо коллекцией, либо массивом, и это приведет к утомленным исключениям ClassCastExceptions, поскольку Hibernate пытается определить идентификатор, вызывая getId () для коллекции или массива (что неверно). ). Это происходит, например, если вы используете IN-предложение (например, ... ГДЕ департамент IN (: отделы) ...), где «отделы» - это массив или набор сущностей Департамента.

Это потому, что коллекции или массивы должны использовать 'query.setParameterList (paramName, (Object []) value) "или" query.setParameterList (paramName, (Collection) value) "'

Короче говоря:

Я изменил версию @Corey, добавив метод applyNamedParameterToQuery (), который я позаимствовал у org.springframework.orm.hibernate3.HibernateTemplate.applyNamedParameterToQuery (Query, String, Object):

import java.sql.SQLException;
import java.util.List;

import org.apache.poi.hssf.record.formula.functions.T;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;

public class HibernateCallbackImpl 
    implements HibernateCallback<List<T>> {

    private String queryString;
    private String[] paramNames;
    private Object[] values;

    private int firstResult;
    private int maxResults;

    /**
     * Fetches a {@link List} of entities from the database using pagination.
     * Execute HQL query, binding a number of values to ":" named parameters in the query string.
     * 
     * @param queryString a query expressed in Hibernate's query language
     * @param paramNames the names of the parameters
     * @param values the values of the parameters 
     * @param firstResult a row number, numbered from 0
     * @param maxResults the maximum number of rows
     */
    public HibernateCallbackImpl(
            String queryString, 
            String[] paramNames, 
            Object[] values,
            int firstResult,
            int maxResults) {
        this.queryString = queryString;
        this.paramNames = paramNames;
        this.values = values;

        this.firstResult = firstResult;
        this.maxResults = maxResults;
    }

    @Override
    public List<T> doInHibernate(Session session) throws HibernateException,
            SQLException {
        Query query = session.createQuery(queryString);
        query.setFirstResult(firstResult);
        query.setMaxResults(maxResults);

        // TODO: throw proper exception when paramNames.length != values.length

        for (int c=0; c<paramNames.length; c++) {
            applyNamedParameterToQuery(query, paramNames[c], values[c]);
        }

        @SuppressWarnings("unchecked")
        List<T> result = query.list();

        return result;
    }


     /**
     * Code borrowed from org.springframework.orm.hibernate3.HibernateTemplate.applyNamedParameterToQuery(Query, String, Object)
     * 
     * Apply the given name parameter to the given Query object.
     * @param queryObject the Query object
     * @param paramName the name of the parameter
     * @param value the value of the parameter
     * @throws HibernateException if thrown by the Query object
     */
    protected void applyNamedParameterToQuery(Query queryObject, String paramName, Object value)
            throws HibernateException {

        if (value instanceof Collection) {
            queryObject.setParameterList(paramName, (Collection) value);
        }
        else if (value instanceof Object[]) {
            queryObject.setParameterList(paramName, (Object[]) value);
        }
        else {
            queryObject.setParameter(paramName, value);
        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...