Критерии имеют некоторые преимущества перед использованием JPQL или необработанного SQL, как описано в this answer: тип безопасности; рефакторинг; меньше зависимости от строк (но все же есть некоторые). И один очень большой недостаток: они менее читабельны и просто уродливы. Существует ли (не JPA) Java API для доступа к реляционным базам данных, которые являются как типичными, так и читабельными?Более приемлемая альтернатива критериям API
ответ
Timo Westkämper сделал хорошую работу с QueryDSL. Эта библиотека предоставляет DSL для запроса различных поставщиков персистентности (JPA, MongoDB, Lucene ...).
Но я часто использовал ручные решения, упрощающие большинство распространенных запросов (список объектов, ограничивающих некоторые из его полей), что мешает мне писать всегда одни и те же строки. Для большинства сложных запросов я переключился на нечитаемый и подробный API критериев.
MyBatis является первой рамки класса Упорство, с поддержкой пользовательских SQL, хранимых процедур и передовых отображений. MyBatis устраняет практически весь код JDBC и ручную настройку параметров и поиск результатов. MyBatis может использовать простые XML или аннотации для примитивов конфигурации и карты, интерфейсы карт и Java POJO (простые старые объекты Java) для записей базы данных.
Или, как nobeh suggested: jOOQ.
В связи с этим вы можете взглянуть на [jOOQ] (http://www.jooq.org/) или [JDBI] (http://www.jdbi.org/). – nobeh
jOOQ, да; JDBI, нет - JDBI имеет одинаковую зависимость от непрозрачных строк, которые делает JPQL. –
Я нашел «окончательное» решение для облегчения поиска JPA в лице следующего класса утилиты: DynamicQueryBuilder
Это дает мета-модель, так что вам не нужно будет описывать отношения с помощью объединений ,
Он ищет по шаблону pojo !!! Просто поместите значения в экземпляр сущности, и они будут использоваться в качестве критериев!
Он использует шаблон строителя, поэтому он ОЧЕНЬ удобочитаемый!
Bank bank = новый Bank(); bank.setId (12L); bank.setAchCode ("1213"); bank.setCbeCode ("1234"); bank.setStatus (новые поисковые запросы (1L)); bank.setAchShortName ("121");
Список идентификаторов = новый ArrayList(); ids.add (1); ids.add (2); ids.add (3); ids.add (4); ids.add (5);
Список cbeCodes = new ArrayList(); cbeCodes.add ("1111"); cbeCodes.add ("2222");
DynamicQueryBuilder queryDyncBuilder1 = новый DynamicQueryBuilder.Builder (null) .select (bank) .withOperType (Operator.OperType.AND). withAdvancedParam ("cbeCode", КАК, PERCENT_AROUND) .withAdvancedParam ("Идентификатор", IN, идентификаторы) .withAdvancedParam ("achCode", между, cbeCodes) .withAdvancedParam ("achShortName", GT) .orderBy ("ID") .orderBy ("cbeCode", true) .orderBy ("status.code", true) .build();
System.out.println (queryDyncBuilder1.getQueryString());
Если вы запустите выше вызов компонента будет построить следующий результате JPQL запрос:
SELECT b
FROM Bank b
WHERE b.status = :status
AND b.cbeCode LIKE :cbeCode
AND b.achShortName > :achShortName
AND b.id IN :id
AND (b.achCode BETWEEN :achCodeFrom AND :achCodeTo)
ORDER BY b.status.code DESC, b.id ASC, b.cbeCode DESC
«Он использует шаблон построения, чтобы он был очень читабельным». Мне нравится QueryDSL в этом отношении еще немного. –
[Другой предложил прочитать] (http://stackoverflow.com/q/825141/248082) – nobeh