A statement locator which makes use of StringTemplate 3.0
for locating templates. Specifically, if a statement doesn't look like SQL based on its first token (ie, it starts
lexing it as sql, and if it fails, it treats it as a name), it splits the name into pieces on colons. The first token
is the string template group file, the second is the template name. Consider the following tests.stg
,
which is adapted from the one in the unit tests, and is loaded via the ClasspathStatementLocator
:
group tests; insert_one() ::= "insert into something (id, name) values (7, 'Martin')" parameterized_insert(table, column_one, column_two) ::=<< insert into $table$ ($column_one$, $column_two$) values (:column_one, :column_two) >>
This defines two templates, the first has no parameters and is used like this:
public void testSimpleTemplate() throws Exception { final Handle h = openHandle(); final int count = h.insert("tests:insert_one"); assertEquals(1, count); }
This looks for a template group named "tests" and a template in that group named "insert_one". Template
groups are located by providing a StringTenmplateGroupLoader
to the statement locator, which
is responsible for loading template groups. The included one looks on the class path, in this case for a
file named "tests.stg" which would be relative to the roots passd in the the ClasspathGroupLoader
's
constructor, or the root of the classpath if none were.
Template parameters are bound from values in the StatementContext
, such as the following:
public void testParameterizedInsert() throws Exception { final Handle h = openHandle(); final int count = h.createStatement("tests:parameterized_insert") .define("table", "something") .define("column_one", "id") .define("column_two", "name") .bind("column_one", 7) .bind("column_two", "Rebecca") .execute(); assertEquals(1, count); }
This one uses the parameters defined in the define(..)
calls, which populate the
values onto the StatementContext
for the statement.