Многие сравнивают JOOQ с MyBatis . Оба они рассматриваются как популярные альтернативы стандарту устойчивости Java в JPA, так как оба они гораздо более ориентированы на SQL, чем сам JPA. При сравнении двух инструментов первое очевидное отличие заключается в следующем:
- jOOQ — это внутренний язык, специфичный для предметной области, моделирующий SQL через свободный API Java .
- MyBatis — это механизм шаблонирования и отображения SQL на основе XML, в котором динамический SQL может создаваться с помощью XML-DSL.
Текущий успех MyBatis в основном основан на том, что он предоставил жизнеспособную альтернативу JPA в то время, когда JPA был еще спорным стандартом, и когда JPA пришлось доказать, что он лучше, чем JDO , что решает очень похожие проблемы. Эта предоставленная альтернатива — то, что нравится многим пользователям, ориентированным на SQL:
- Разделение кода Java и SQL, извлечение кода SQL во внешние файлы. Это позволяет администраторам баз данных исправлять строки SQL в продуктивной среде, добавлять подсказки и выполнять другие настройки.
- Автоматическое сопоставление данных табличных результатов с объектами. Это также достигается в том же XML DSL, что и спецификация динамического SQL.
Реализация шаблонов SQL с помощью jOOQ
Эти вещи могут быть достигнуты и с JOOQ . Но в отличие от MyBatis, SQL-шаблоны jOOQ (как будет представлено в jOOQ 3.2) не будут использовать проприетарный язык шаблонов. Вы должны иметь возможность самостоятельно выбирать язык, предоставляя jOOQ очень простой адаптер. Это позволит использовать:
- Apache Velocity
- StringTemplate
- Freemarker
- Затмение Xtend
- XSLT
- … или даже собственный шаблонный адаптер для файлов XML MyBatis при миграции с MyBatis на jOOQ
Давайте посмотрим на пример шаблона Velocity. В этом примере добавляется динамический список параметров ID в предложение WHERE:
SELECT a.first_name, a.last_name, count(*) FROM t_author a LEFT OUTER JOIN t_book b ON a.id = b.author_id WHERE 1 = 0 #foreach ($param in $p) OR a.id = ? #end GROUP BY a.first_name, a.last_name ORDER BY a.id ASC
Приведенный выше шаблон может быть передан следующей реализации шаблона jOOQ, которая использует произвольные входные объекты для создания конкретного jOOQ QueryPart. QueryPart — это объект, который может отображать переменные SQL и связывать:
class VelocityTemplate
implements org.jooq.Template {
private final String file;
public VelocityTemplate(String file) {
this.file = file;
}
@Override
public QueryPart transform(Object... input) {
// Velocity code
// -----------------------------------------
URL url = this.getClass().getResource(
"/org/jooq/test/_/templates/");
File file = url.getFile();
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RESOURCE_LOADER, "file");
ve.setProperty(FILE_RESOURCE_LOADER_PATH,
new File(file ).getAbsolutePath());
ve.setProperty(FILE_RESOURCE_LOADER_CACHE,
"true");
ve.init();
VelocityContext context = new VelocityContext();
context.put("p", input);
StringWriter writer = new StringWriter();
ve.getTemplate(file, "UTF-8")
.merge(context, writer);
// jOOQ Code
// -----------------------------------------
return DSL.queryPart(writer.toString(), input);
}
}
Очень простой клеевой код. Поскольку у вас есть полный контроль над адаптером реализации механизма шаблонов, вы также можете добавить в свой адаптер кэширование, пулы объектов и т. Д.
Приведенный выше шаблон можно легко использовать в API jOOQ, где jOOQ допускает простой SQL. Например, как запрос верхнего уровня:
Template tpl = new VelocityTemplate( "authors-and-books.vm"); DSL.using(configuration) .resultQuery(tpl, 1, 2, 3) .fetch();
Или в виде вложенного выбора, встроенного в типичный DSL jOOQ:
DSL.using(configuration)
.select()
.from(new TableSourceTemplate("my-table.vm"))
.fetch();
Конечно, вы также можете воспользоваться функциями отображения записей в jOOQ, которые позволяют вам реализовать собственные алгоритмы отображения таблиц в объекты. Часто это может быть лучшим выбором, чем полагаться на любую аппаратную конфигурацию XML, такую как MyBatis:
List<MyType> result =
DSL.using(configuration)
.select()
.from(new TableSourceTemplate("my-table.vm"))
.fetch(new RecordMapper<Record, MyType>() {
public MyType map(Record record) {
// Custom mapping logic here
}
});
или с Java 8:
List<MyType> result =
DSL.using(configuration)
.select()
.from(new TableSourceTemplate("my-table.vm"))
.fetch((Record) -> new MyType().init(record));
Возможности велики
Шаблонирование SQL является мощным инструментом, когда вы предпочитаете простой, основанный на строках SQL, который можно время от времени настраивать с помощью небольшого цикла или оператора if, чтобы вставить какое-то динамическое предложение SQL. Есть несколько механизмов SQL, которые пытаются решить эту проблему тем или иным способом:
- MyBatis — ведущий шаблонизатор Java SQL
- jOOQ — ведущий Java SQL Builder и интеграция с языком SQL
- ElSql — легкий инструмент, разработанный Стивеном Колебурном
- JIRM — легкий инструмент, созданный Адамом Гентом
Среди всего вышеперечисленного все инструменты поставляются с простым проприетарным языком шаблонов, но jOOQ — единственный, который поощряет вас использовать выбранный вами шаблонизатор и, таким образом, предлагает произвольную расширяемость шаблонов в будущем.