Skip to main content

6.3 SQL Text Substitution

Please note

${...} substitutes text directly; it is not PreparedStatement binding. For table names, columns and ordering, map application allowlist choices to fixed SQL fragments rather than accepting raw user input.

Use ${...} to fetch named arguments and inject the result into SQL text.

Example: Choose a sort fragment from an allowlist
select * from users where id > #{id} order by ${order}

Basic Usage​

Map<String, Object> args = CollectionUtils.asMap(
"id", 2,
"order", "name desc"
);
jdbcTemplate.queryForList("select * from users where id > #{id} order by ${order}", args);

Common Scenarios​

${...} is suitable for scenarios where the SQL structure itself needs to change dynamically, for example:

Dynamic table name
select * from ${tableName} where id = #{id}
Dynamic column names
select ${columns} from users where id = #{id}
Dynamic ordering
select * from users order by ${orderBy}

Difference from #{...}​

SyntaxBehaviorSafety
#{...}Generates a ? placeholder and binds the argument value via PreparedStatementSeparates values from SQL structure; the application must still control SQL templates and OGNL expressions
${...}Evaluates via OGNL and splices the result directly into the SQL stringUnsafe, SQL injection risk
Principle

Prefer #{...}. Only use ${...} when the SQL structure (table name, column name, ordering, etc.) needs to change dynamically.