Я работаю с 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;
}
}
Что вы думаете о такой уловке? Знаете ли вы поддерживаемые инструменты сообщества, которые делают почти такие вещи?