Querying the Database

Writing the data

Other Usage

Misc

Query Tutorial

Bind positional parameters

Use ? for data values and pass parameters in the same order:

Map<String, Object> row =
        new Action(conn, "SELECT * FROM shop_address WHERE id = ? AND stat = ?")
                .query(1, 0)
                .one();

The values are bound by PreparedStatement; do not quote the ? placeholders.

SQL template parameters

If the first argument is a Map, Action renders an inline SQL template when the SQL contains a dynamic node or a named placeholder, then binds any remaining positional parameters:

Named data parameters: #{}

Use #{name} for ordinary values in the Map. It generates a JDBC ? placeholder, and values are bound in SQL occurrence order. It is therefore safe for fields originating from a query string, form, or JSON request body:

Map<String, Object> params = new HashMap<>();
params.put("id", 1);
params.put("name", "Alice");

Map<String, Object> row =
        new Action(conn, "SELECT * FROM shop_address WHERE id = #{id} AND name = #{name}")
                .query(params)
                .one();

The JDBC SQL for the example is equivalent to SELECT * FROM shop_address WHERE id = ? AND name = ?. Use #{} for values in SELECT, INSERT, UPDATE, and DELETE; do not add quotes around the placeholder yourself.

Identifier parameters: ${}

Map<String, Object> template = new HashMap<>();
template.put("tableName", "shop_address");

Map<String, Object> row =
        new Action(conn, "SELECT * FROM ${tableName} WHERE id = ?")
                .query(template, 1)
                .one();

${...} is restricted to SQL identifiers, including qualified names such as schema.table; arbitrary SQL fragments are rejected. It is not for ordinary request values: WHERE id = ${id} rejects an id=1 value, so write WHERE id = #{id} instead. Table names, column names, sort fields, and sort direction are SQL structure and cannot be JDBC-bound; even when an identifier passes syntax validation, the application must constrain it through server-side configuration, an allowlist, and authorization.

Map column names

Map results use JDBC column labels. Give expressions an alias when you need a stable key:

Map<String, Object> totals =
        new Action(conn, "SELECT COUNT(*) AS total FROM shop_address")
                .query()
                .one();

Object total = totals.get("total");

Map to a JavaBean

The target class needs a no-argument constructor and writable properties:

Address address =
        new Action(conn, "SELECT id, name, create_date FROM shop_address WHERE id = ?")
                .query(1)
                .one(Address.class);

SqlMan converts underscore column names such as create_date to Java property names such as createDate.