JDBI3动态创建WHERE子句

时间:2018-10-18 08:55:10

标签: java jdbi

如何在哪里创建动态

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

JDBI How can I dynamically create a WHERE clause while preventing SQL Injection?

但实际上不是JDBI3

1 个答案:

答案 0 :(得分:2)

在查询中实现动态过滤的主要方法有两种:

  • 使用静态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值的行。
  • 如果两个参数都为null,则将返回所有行。

模板引擎方法

开箱即用,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>