Многие сравнивают 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 — единственный, который поощряет вас использовать выбранный вами шаблонизатор и, таким образом, предлагает произвольную расширяемость шаблонов в будущем.