数据库查询

写入数据

其他用法

Misc

XML SQL

为什么要在 XML 中使用 SQL?

像著名的 MyBatis 框架一样,SQL 语句可以存储在 XML 文件中。这种方式有其特定的原因。以下是在 XML 中存储 SQL 的一些优点:

  1. 关注点分离:将 SQL 语句保存在 XML 文件中有助于将 SQL 逻辑与 Java 代码分离。这使代码库更加整洁,更易于管理。
  2. 可读性:当存储在 XML 中时,长 SQL 语句可以更具可读性。XML 文件的结构可以帮助使 SQL 查询更有条理,更易于理解。
  3. 可维护性:当 SQL 语句存储在 XML 中时,无需更改 Java 代码就可以更轻松地更新和维护它们。这对于具有大量 SQL 查询的大型项目特别有用。

SqlMan 在处理 SQL 语句方面采用了类似 MyBatis 的方法。

SmallMyBatis 可以把 SQL 保存在 classpath 下的 XML 资源中。它是轻量 SQL 模板工具,并不是完整的 MyBatis Mapper 或 ORM。

定义 SQL

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <sql id="address-count">
        SELECT COUNT(*) AS total FROM shop_address
    </sql>

    <sql id="address-by-id">
        SELECT * FROM shop_address WHERE id = ?
    </sql>

    <sql id="address-by-status">
        SELECT * FROM ${tableName}
        <if test="stat != null">
            WHERE stat = #{stat}
        </if>
    </sql>
</root>

同一个 SmallMyBatis 实例中的 SQL ID 共用一张映射表。加载重复 ID 时,后加载的 SQL 会覆盖原内容并记录警告。

加载和执行

SmallMyBatis mapper = new SmallMyBatis();
mapper.loadXML("sql/mysql.xml");

String sql = mapper.getSqlById("address-by-id");
Address address = new Action(conn, sql).query(12L).one(Address.class);

loadXML(...) 可以一次加载多个资源。loadBySqlLocations(...) 支持 Spring 资源匹配模式:

mapper.loadBySqlLocations("classpath*:sql/**/*.xml");

动态条件

handleSql(params, sqlId) 使用 Spring 表达式执行 <if test="...">,然后处理占位符:

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

String sql = mapper.handleSql(params, "address-by-status");
List<Map<String, Object>> rows = new Action(conn, sql).query().list();

XML 中的比较符可以写成 &lt;&gt;,生成 SQL 时会恢复为原符号。

占位符安全

不要把请求参数或其他不可信输入传给 ${...}#{...}handleSql(...) 当前没有启用 <forEach> 解析,文档和业务代码不应依赖该标签。