域名 AXUM.RS 将于 2025 年 10 月到期。我们无意再对其进行续费,如果你有意接续这个域名,请与我们取得联系。
  • AXUM.RS 现仅需人民币 3000 元(大写:叁仟元整。接受适度议价
  • 按照行业规则,AXUM.RS 到期后,大概率会进入长时间的赎回期,该期间内,如果你想拥有该域名,将要付出高额的费用
  • 我们已启用 AXUM.EU.ORG 域名,并将持续运营
  • 仅接受微信或支付宝交易
如果你对 AXUM.RS 有兴趣,请和我们进行联系:

使用sqlx的QueryBuilder构建复杂、动态的查询

本章我们讨论如何优雅方便地使用 sqlx 构建复杂的、动态的 SQL。sqlx 提供了 QueryBuilder 结构体,它可以方便地实现 SQL 的构建。

QueryBuilder 常用方法

**十分重要:和 query()/query_as()不同,QueryBuilderpush()方法的 SQL 语句里,不需要使用 ? 占位符

// query_as
sqlx::query_as("SELECT * FROM member WHERE id=? AND is_del=?").bind(id).bind(false);

// QueryBuild
let mut q = QueryBuilder::new("SELECT * FROM member WHERE id="); // 不用占位符!
q.push_bind(id)
.push(" AND is_del=") // 不用占位符!
.push_bind(false);

使用 QueryBuilder 改造 list()

改造前:

改造后:

使用 QueryBuilder 改造 exists()

改造前:

改造后:

pub async fn exists(conn: &sqlx::MySqlPool, name: &str, id: Option<u32>) -> Result<bool> {
    let mut q = sqlx::QueryBuilder::new("SELECT COUNT(*) FROM member WHERE name=");
    q.push_bind(name);

    if let Some(id) = id {
        q.push(" AND id<>").push_bind(id);
    };

    let count: (i64,) = q
        .build_query_as()
        .fetch_one(conn)
        .await
        .map_err(Error::from)?;

    Ok(count.0 > 0)
}

对比发现,使用 QueryBuilder 改造后的 exists() 逻辑清晰,代码简洁。

再次提醒:**和 query()/query_as()不同,QueryBuilderpush()方法的 SQL 语句里,不需要使用 ? 占位符

再次提醒:**和 query()/query_as()不同,QueryBuilderpush()方法的 SQL 语句里,不需要使用 ? 占位符

本章代码位于06/QueryBuilder分支 。

要查看完整内容,请先登录