Как кто-то может дать HQL / SQL лучший ОО подход? - PullRequest
4 голосов
/ 06 мая 2011

Я работаю с Hibernate и, в частности, с API-интерфейсом Criteria для способа создания предикатов запросов, но в некоторых случаях его невозможно использовать, поэтому мне приходится использовать HQL / SQL.

Что мне не нравится в построении запросов HQL / SQL, так это в основном потому, что, помимо того, что это не OO, сложно составлять предикаты, как мы можем делать с Criteria. Мне не нравится подход для построения полной строки запроса, построения этого запроса и просто добавления всех параметров запроса.

Кто-нибудь знает здесь инструменты, позволяющие упростить написание и повторное использование запросов HQL / SQL в Hibernate / JPA?

На самом деле я создал небольшой класс, который позволяет мне создавать часть запроса и часть параметров одновременно. Я предполагаю, что он может не отвечать ни на чей случай, но он все еще хорошо работает для моего простого варианта использования: я в основном делаю композицию предикатов с AND и OR в предложении where.

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;

/**
 * This permits to append to query step by step and give a better lisibility to some queries
 * Works with hql and sql
 * 
 * @author Sebastien Lorber (<i>lorber.sebastien@gmail.com</i>)
 */
public class AppendableQuery  {

    private Map<String,Object> parameters;
    private Map<String,Collection<? extends Object>> parametersLists;
    private StringBuilder queryBuilder;

    /**
     * Creates a new empty query
     */
    public AppendableQuery() {
        parameters = new HashMap<String, Object>();
        parametersLists = new HashMap<String, Collection<? extends Object>>();
        queryBuilder = new StringBuilder();
    }

    /**
     * Append to the query
     * @param querySubstring
     */
    public AppendableQuery append(String querySubstring) {
        queryBuilder.append(querySubstring);
        return this;
    }

    /**
     * Set a parameter to the query
     * @param paramKey
     * @param paramValue
     */
    public AppendableQuery setParameter(String paramKey,Object paramValue) {
        parameters.put(paramKey, paramValue);
        return this;
    }

    /**
     * Set a parameter list to the query
     * @param paramKey
     * @param paramValue
     * @return
     */
    public AppendableQuery setParameterList(String paramKey,Collection<? extends Object> paramValue) {
        parametersLists.put(paramKey, paramValue);
        return this;
    }

    /**
     * Gets an HQL query based on what you filled
     * @param hibernateSession
     * @return SQL query
     */
    public Query getHQLQuery(Session hibernateSession) {
        Query query = hibernateSession.createQuery(queryBuilder.toString());
        for ( Map.Entry<String, Object> entry : parameters.entrySet() ) {
            query.setParameter(entry.getKey(), entry.getValue());
        }
        for ( Map.Entry<String, Collection<? extends Object>> entry : parametersLists.entrySet() ) {
            query.setParameterList(entry.getKey(), entry.getValue());
        }
        return query;
    }

    /**
     * Gets an SQL query based on what you filled
     * @param hibernateSession
     * @return SQL query
     */
    public SQLQuery getSQLQuery(Session hibernateSession) {
        SQLQuery query = hibernateSession.createSQLQuery(queryBuilder.toString());
        for ( Map.Entry<String, Object> entry : parameters.entrySet() ) {
            query.setParameter(entry.getKey(), entry.getValue());
        }
        for ( Map.Entry<String, Collection<? extends Object>> entry : parametersLists.entrySet() ) {
            query.setParameterList(entry.getKey(), entry.getValue());
        }
        return query;
    }

}

Что вы думаете о такой уловке? Знаете ли вы поддерживаемые инструменты сообщества, которые делают почти такие вещи?

Ответы [ 2 ]

1 голос
/ 08 мая 2011

Для более конструирования в стиле OO вы можете использовать Liquidform или Querydsl . Liquidform - это более легкий инструмент, не требующий генерации кода, а Querydsl имеет несколько большие накладные расходы, но с более читаемым и компактным синтаксисом Также я считаю, что экспрессивность Querydsl выше.

Нет необходимости в развертывании собственного компоновщика JPQL, для этого уже есть проверенные решения.

Поскольку я поддерживаю Querydsl, этот ответ предвзят.

1 голос
/ 06 мая 2011

Я думаю, QueryDSL имеет некоторые средства интеграции SQL / JPQL / HQL с JPA.

Если Hibernate / JPA не является обязательным, вы можете взглянуть на jOOQ , среда абстракции базы данных Java, которую я написал.Он поддерживает почти все стандартные и нестандартные конструкции SQL, но при этом объектно-ориентированный.

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