域名 AXUM.RS 将于2025年10月到期。我们无意再对其进行续费,我们希望你能够接续这个域名,让更多 AXUM 开发者继续受益。现在,我们已启用新域名 AXUM.EU.ORG
  • 方案AXUM.RS 域名 = 3000
如果你有意接续这份 AXUM 情怀,请与我们取得联系。
说明:
  1. 如果有人购买 AXUM.RS 域名,或者该域名到期,本站将使用免费域名 AXUM.EU.ORG 继续提供服务。

sqlx实现增删改

本章将讨论使用 sqlx 进行增删改(INSERT/DELETE/UPDATE)操作。

判断是否存在

开始之前,我们需要定义一个函数,用于判断增加或修改的会员是否存在。在数据库中,我们将 name 字段定义成了 unique,所以只需要判断是否存在相同 name 的记录就行了。

// src/db/member.rs

pub async fn exists(conn: &sqlx::MySqlPool, name: &str, id: Option<u32>) -> Result<bool> {
    let sql = "SELECT COUNT(*) FROM member WHERE name=?";
    let with_id_sql: String;

    let q = match id {
        Some(id) => {
            with_id_sql = format!("{} AND id<>?", sql);
            sqlx::query_as(&with_id_sql).bind(&name).bind(id)
        }
        None => sqlx::query_as(sql).bind(&name),
    };

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

    Ok(count.0 > 0)
}

原理很简单,就是通过 SELECT COUNT(*) 来统计指定 name 的记录数,如果这个记录大于0,说明该会员已经存在。

这里有个很奇怪的 id: Option<u32>,它是做什么用的?

  • 对于增加记录来说,只要判断是否存在指定 name的记录就行了
  • 对于修改记录来说,除了要判断是否存在指定 name 的记录,还要判断这个记录是否是它自己。如果不加这个条件,即使不做任何数据的修改,都无法进行操作,exists() 永远返回 true

增加

结合 query()execute(),我们执行了 INSERT 语句,并返回了它最后插入的ID。为什么返回的时候要转成 u32Ok(id as u32))呢?

修改

逻辑删除

// src/db/member.rs

pub async fn del(conn: &sqlx::MySqlPool, id: u32) -> Result<u64> {
    let aff = sqlx::query("UPDATE member SET is_del=true WHERE id=?")
        .bind(id)
        .execute(conn)
        .await
        .map_err(Error::from)?
        .rows_affected();
    Ok(aff)
}

逻辑删除说到底就是将 is_del 字段的值改成 true,它就是一个 UPDATE 操作。

物理删除

// src/db/member.rs

pub async fn real_del(conn: &sqlx::MySqlPool, id: u32) -> Result<u64> {
    let aff = sqlx::query("DELETE FROM member WHERE id=?")
        .bind(id)
        .execute(conn)
        .await
        .map_err(Error::from)?
        .rows_affected();
    Ok(aff)
}

结合 query()execute(),我们执行了 DELETE 语句,并返回了受影响的行数。

本章代码位于04/增删改分支

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