'jdbi version 3, stringtemplate when to escape <, > characters?

I am using jdbi3 with StringTemplate 4 templating engine, I have this test query:

    @SqlQuery("select * from test "
        + "where field1 = 5"
        + "<if(cond1)> or field2 \\<= :value1<endif>"
        + "<if(cond2)> or field2 >= :value2<endif>"
        + "<if(cond3)> or field2 in (<values>)<endif>")
@RegisterBeanMapper(Test.class)
@UseStringTemplateEngine
public List<Test> selectTest(
        @Define("cond1") boolean cond1, @Bind("value1") int value2,
        @Define("cond2") boolean cond2, @Bind("value2") int value3,
        @Define("cond3") boolean cond3,
        @BindList(value="values", onEmpty=BindList.EmptyHandling.NULL_STRING ) List<Integer> values);

Using StringTemplate engine when I have to escape with \ the characters < or > in the query? Testing I found that I have to escape <= in the query like I did.

In the IN clause using @BindList I have to use the <values> but in this case I was expecting to escape it like \\<values> otherwise it will be used as attribute by StringTemplate but if I do this the query doesn't work.

About >= escaping it or not seems the same in the query.



Solution 1:[1]

Introduction

Let's consider:

  • The 3.27.1 Jdbi version as the current Jdbi version.
  • The 4.3.1 StringTemplate version as the current StringTemplate version, since the current Jdbi version uses it. Please, see: jdbi/pom.xml at v3.27.1 · jdbi/jdbi.

Answer

Jdbi

Documentation: Which characters to escape

Please, note the warning on which characters to escape:

Since StringTemplate by default uses the < character to mark ST expressions, you might need to escape some SQL: String datePredSql = "<if(datePredicate)> <dateColumn> \\< :dateFilter <endif>"

jdbi/index.adoc at v3.27.1 · jdbi/jdbi.

Unit-test: Do not escape @BindList variable name

Please, see the BindListTest.ifValueGivenWithNullValueOptionThenResultIsTruthy() test method: jdbi/BindListTest.java at v3.27.1 · jdbi/jdbi.

Please, note that the test covers a very similar annotated method:

@SqlQuery("select name from something <if(name)> where name in (<name>) <endif>")
@UseStringTemplateEngine
List<String> getForValue(@Nonnull @BindList(value = "name", onEmpty = NULL_VALUE) List<String> name);

Please, note that the @BindList variable name is not escaped:

in (<name>)

StringTemplate

Documentation: Which characters to escape

Please, note which characters to escape:

A template is a sequence of text and expression elements, optionally interspersed with comments. At the coarsest level, the basic elements are:

text
<expr>
<! comment !>

Escape delimiters with a backslash character: \< or \>.

stringtemplate4/templates.md at 4.3.1 · antlr/stringtemplate4.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sergey Vyacheslavovich Brunov