📢 Enterprise v4.7.2 Released

Enhanced AI SQL Writing feature, supports generating dynamic SQL

Skip to content

SQL Writing Guidelines ​

Dynamic SQL Tag Syntax ​

Dynamic SQL functionality allows us to construct SQL statements dynamically based on conditions. By using specific tags, we can easily implement complex SQL logic. Below are the commonly used dynamic SQL tags and their usage.

1. if Tag ​

The if tag is used for conditional evaluation, similar to an if statement in Java.

xml
SELECT * FROM BLOG WHERE state = 'ACTIVE'
<if test="title != null">
  AND title like #{title}
</if>

Parameter Example ​

json
{
  "title": "MyBlog"
}

Resulting SQL Query ​

sql
SELECT * FROM BLOG WHERE state = 'ACTIVE' AND title like ?

2. choose, when, otherwise Tags ​

These tags function similarly to a switch statement in Java.

xml
SELECT * FROM BLOG WHERE state = 'ACTIVE'
<choose>
  <when test="title != null">
    AND title = #{title}
  </when>
  <when test="author != null and author.name != null">
    AND author_name = #{author.name}
  </when>
  <otherwise>
    AND featured = 1
  </otherwise>
</choose>

Parameter Example ​

json
{
  "title": "MyBlog",
  "author": {
    "name": "AuthorName"
  }
}

Resulting SQL Query ​

sql
SELECT * FROM BLOG WHERE state = 'ACTIVE' AND title = ?

3. trim, where, set Tags ​

These tags are used to handle prefixes, suffixes, and conjunctions in SQL queries.

trim Tag ​

The trim tag allows for customized string trimming.

xml
SELECT * FROM BLOG 
<trim prefix="WHERE" prefixOverrides="and |or ">
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null">
    AND author_name like #{author.name}
  </if>
</trim>
Parameter Example ​
json
{
  "title": "MyBlog",
  "author": {
    "name": "AuthorName"
  }
}
Resulting SQL Query ​
sql
SELECT * FROM BLOG WHERE title like ? AND author_name like ?

where Tag ​

The where tag dynamically adds the WHERE keyword at the beginning of the generated SQL statement and removes the first AND or OR keyword.

xml
SELECT * FROM BLOG 
<where>
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null">
    AND author_name like #{author.name}
  </if>
</where>
Parameter Example ​
json
{
  "title": "MyBlog",
  "author": {
    "name": "AuthorName"
  }
}
Resulting SQL Query ​
sql
SELECT * FROM BLOG WHERE title like ? AND author_name like ?

set Tag ​

The set tag is used for dynamically updating SQL statements, intelligently adding the SET keyword and removing the final comma.

xml
UPDATE BLOG
<set>
  <if test="title != null">title = #{title},</if>
  <if test="author != null">author_name = #{author.name},</if>
</set>
WHERE id = #{id}
Parameter Example ​
json
{
  "title": "MyBlog",
  "author": {
    "name": "AuthorName"
  },
  "id": 123
}
Resulting SQL Query ​
sql
UPDATE BLOG SET title = ?, author_name = ? WHERE id = ?

4. foreach Tag ​

The foreach tag is primarily used to iterate over collections, often employed to build IN clauses.

xml
SELECT * FROM BLOG
WHERE id in
<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
  #{item}
</foreach>

Parameter Example ​

json
{
  "list": [1, 2, 3, 4, 5]
}

Resulting SQL Query ​

sql
SELECT * FROM BLOG WHERE id in (?, ?, ?, ?, ?)

5. bind Tag ​

The bind tag creates a variable and binds the value of an OGNL expression to that variable.

xml
<bind name="pattern" value="'%' + title + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}

Parameter Example ​

json
{
  "title": "MyBlog"
}

Resulting SQL Query ​

sql
SELECT * FROM BLOG WHERE title LIKE ?

SQL Parameter Injection ​

In dynamic SQL, both #{} and ${} are used for parameter substitution, but they differ significantly in how they handle parameters.

Usage of #{} ​

  1. Precompiled Processing: #{} is preprocessed, equivalent to the ? placeholder in JDBC. It replaces #{} with ?, performs precompilation, and sets parameters via PreparedStatement.
  2. Automatic Escaping: #{} effectively prevents SQL injection by automatically escaping input parameters.
  3. Type Handling: #{} handles type conversions for incoming parameters.

Example:

sql
SELECT * FROM BLOG WHERE title LIKE #{title}

With title = "MyBlog", the resulting SQL becomes:

sql
SELECT * FROM BLOG WHERE title LIKE ?

Usage of ${} ​

  1. Direct Substitution: ${} directly substitutes the parameter value into the SQL statement without precompilation. Therefore, caution is required when using ${} to avoid SQL injection risks.
  2. No Escaping: ${} does not escape input parameters, making it suitable for dynamically generating table names or column names.
  3. No Type Conversion: ${} bypasses type handling and uses the parameter's toString() method directly.

Example:

xml
SELECT * FROM BLOG WHERE title LIKE '${title}'

With title = "MyBlog", the resulting SQL becomes:

sql
SELECT * FROM BLOG WHERE title LIKE 'MyBlog'
  • Use #{}: In most cases, especially when dealing with user inputs, prioritize #{} to prevent SQL injection.
  • Use ${}: Use ${} when dynamically generating table or column names, ensuring that the input parameters are safe.

System Built-in Variables ​

DBAPI internally includes the variable __clientId, which retrieves the current client ID and can be directly used as an SQL parameter.

Usage Example:

sql
SELECT * FROM users WHERE client_id = #{__clientId}

Special Character Escaping ​

Escaping Less-than Signs ​

Less-than signs < in SQL statements must be escaped as &lt;.

Incorrect Example:

sql
-- Incorrect: Causes XML parsing errors
SELECT * FROM users WHERE age < 18

Correct Example:

sql
-- Correct: Uses escaped characters
SELECT * FROM users WHERE age &lt; 18