JDBI3 динамически создает предложение WHERE - PullRequest
0 голосов
/ 18 октября 2018

Как я могу создать динамически, где

public interface ThingDAO {
   @SqlQuery("SELECT * FROM things <where>)
   List<Thing> findThingsWhere(@Define("where") String where);
}

JDBI Как я могу динамически создать предложение WHERE, предотвращая SQL-инъекцию?

Но на самом деле это не для JDBI3

1 Ответ

0 голосов
/ 24 октября 2018

Существует два основных подхода к достижению динамической фильтрации в запросах:

  • Используйте статическое предложение WHERE, а параметр NULL означает «нет фильтрации по этому параметру».Я рекомендую вам всегда сначала попробовать этот подход.
  • Используйте шаблонизатор.Это требует времени для настройки и проверки и усложняет анализ запросов из-за смешивания SQL и языков шаблонов.Используйте это, когда статическое предложение WHERE не работает для вашего варианта использования, или вы хотите устранить дублирование между несколькими запросами.

Статический WHERE подход предложения:

SELECT * FROM things
WHERE (:foo IS NULL OR foo_column = :foo)
AND (:bar IS NULL or bar_column = :bar)
  • Если :foo равно нулю, то строки things не будут фильтроваться в foo_column.В противном случае будут возвращены только строки с указанным значением :foo.
  • Аналогично, если :bar равно нулю, то things строки не будут отфильтрованы по bar_column.В противном случае будут возвращены только строки с указанным значением :bar.
  • Если оба параметра равны нулю, будут возвращены все строки.

Механизм шаблоновподхода

Из коробки Jdbi 3 предоставляет только простые шаблоны, которые заменяют, например, <where> на ваш параметр @Define("where").

Этот механизм шаблонов по умолчанию может быть заменен любым, что вам нравится.Jdbi предоставляет дополнительные движки шаблонов для StringTemplate 4 и для Freemarker.

StringTemplate 4 больше не поддерживается, поэтому я просто покажу вам пример для Freemarker.

FreeMarker

Добавить зависимость:

<dependency>
  <groupId>org.jdbi</groupId>
  <artifactId>jdbi3-freemarker</artifactId>
</dependency>

Аннотация @UseFreemarkerEngine может использоваться для объекта SQL, что приводит к тому, что запрос сначала отображается как шаблон Freemarker.

@UseFreemarkerSqlLocator похоже на @UseFreemarkerEngine, но с дополнительным бонусом загрузки SQL из файлов на пути к классам.Это позволяет выполнять рефакторинг часто используемых шаблонов SQL в повторно используемые файлы, на которые можно ссылаться с помощью директивы #include.

<#include "/org/jdbi/v3/freemarker/util.ftl">
<#include "util2.ftl">
select name from something
where id in (<#list somethings as something>${something.id}<#sep>, </#list>)
<@groupBy field="name" />
<@orderBy field="name" />

util.ftl:

<#macro orderBy field order="ASC">
  ORDER BY ${field} ${order}
</#macro>

util2.ftl:

<#macro groupBy field>
  GROUP BY ${field}
</#macro>
...