Rust详情修改删除优化

详情优化

接下来我们抽离详情接口

🍎旧的写法

之前我们的写法如下

javascript 复制代码
pub async fn get_user_detail(
    pool: web::Data<MySqlPool>,
    path: web::Path<i32>, // user_id
) -> HttpResponse {
    let user_id = path.into_inner();

    let result = sqlx::query_as::<_, User>("SELECT * FROM sys_user WHERE user_id = ?")
        .bind(user_id)
        .fetch_one(pool.get_ref())
        .await;

    match result {
        Ok(user) => {
            let response = ApiDetailResponse {
                code: 200,
                msg: "查询成功",
                data: user, // 返回数据格式可根据实际需求进行修改
            };
            HttpResponse::Ok().json(response)
        }
        Err(sqlx::Error::RowNotFound) => {
            let response = ApiDetailResponse {
                code: 404,
                msg: "用户不存在",
                data: (),
            };
            HttpResponse::NotFound().json(response)
        }
        Err(e) => {
            eprintln!("查询用户详情失败: {:?}", e);
            let response = ApiDetailResponse {
                code: 500,
                msg: "查询失败",
                data: (),
            };
            HttpResponse::InternalServerError().json(response)
        }
    }
}

🍎抽离出来详情方法

javascript 复制代码
// 通用详情
pub async fn detail_api<T>(
    pool: web::Data<MySqlPool>,
    table: &str,
    pk_field: &str,
    id: i32,
) -> HttpResponse
where
    T: for<'r> FromRow<'r, sqlx::mysql::MySqlRow> + serde::Serialize + Unpin + Send,
{
    let query = format!("SELECT * FROM {} WHERE {} = ?", table, pk_field);
    let result = sqlx::query_as::<_, T>(&query)
        .bind(id)
        .fetch_one(pool.get_ref())
        .await;

    match result {
        Ok(data) => HttpResponse::Ok().json(ApiDetailResponse {
            code: 200,
            msg: "查询成功",
            data: data,
        }),
        Err(sqlx::Error::RowNotFound) => HttpResponse::NotFound().json(BasicResponse {
            code: 404,
            msg: "数据不存在"
        }),
        Err(e) => {
            eprintln!("查询详情失败: {:?}", e);
            HttpResponse::InternalServerError().json(BasicResponse {
                code: 500,
                msg: "查询失败"
            })
        }
    }
}

🍎封装使用详情方法

javascript 复制代码
// 通用详情
pub async fn get_user_detail(
    pool: web::Data<MySqlPool>,
    path: web::Path<i32>,
) -> HttpResponse {
    crate::common::apimethods::detail_api::<User>(pool, "sys_user", "user_id", path.into_inner()).await
}

修改优化

🍎现在的修改接口如下面所示

javascript 复制代码
//更新
#[derive(Serialize)]
pub struct Response {
    code: i32,
    msg: String,
}
pub async fn put_update_users(
    pool: web::Data<Pool<MySql>>, 
    item: web::Json<UpdateUserRequest>
) -> impl Responder {
    let result = sqlx::query!(
        "UPDATE sys_user SET age = ? WHERE user_id = ?",
        item.age,
        item.user_id
    )
    .execute(pool.get_ref())
    .await;

    match result {
        Ok(_) => HttpResponse::Ok().json(Response {
            code: 200,
            msg: "更新成功!".to_string(),
        }),
        Err(e) => {
            eprintln!("数据库更新失败: {:?}", e);
            HttpResponse::InternalServerError().json(Response {
                code: 500,
                msg: "更新失败!".to_string(),
            })
        }
    }
}

🍎修改接口以后

javascript 复制代码
pub async fn update_api(
    pool: &MySqlPool,
    table: &str,
    pk_field: &str,
    pk_value: i32,
    data: &HashMap<String, String>,
) -> HttpResponse {
    // 构建 SET 语句
    let sets: Vec<String> = data.keys().map(|k| format!("{} = ?", k)).collect();
    let sql = format!(
        "UPDATE {} SET {} WHERE {} = ?",
        table,
        sets.join(", "),
        pk_field
    );

    let mut query = sqlx::query(&sql);
    for key in data.keys() {
        query = query.bind(data.get(key).unwrap());
    }
    query = query.bind(pk_value);

    match query.execute(pool).await {
        Ok(_) => HttpResponse::Ok().json(Response {
            code: 200,
            msg: "更新成功!".to_string(),
        }),
        Err(e) => {
            eprintln!("数据库更新失败: {:?}", e);
            HttpResponse::InternalServerError().json(Response {
                code: 500,
                msg: "更新失败!".to_string(),
            })
        }
    }
}

🍎测试接口

我们想要的字段可以更改,其他字段无法更改

返回结果如下

javascript 复制代码
{
    "code": 200,
    "msg": "更新成功!"
}

删除优化

接下来我们抽离删除接口

🍎旧的写法

javascript 复制代码
pub async fn delete_user(
    pool: web::Data<Pool<MySql>>, 
    id: web::Path<i32>  // Path 中包含了用户的 ID
) -> impl Responder {
    // 执行删除操作
    let result = sqlx::query!(
        "DELETE FROM sys_user WHERE user_id = ?",
        *id  // 解引用 Path 获取具体的值
    )
    .execute(pool.get_ref())
    .await;
    match result {
        Ok(_) => HttpResponse::Ok().json(BasicResponse {
            code: 200,
            msg: "删除成功!",
        }),
        Err(e) => {
            eprintln!("数据库删除失败: {:?}", e);
            HttpResponse::InternalServerError().json(BasicResponse {
                code: 500,
                msg: "删除失败!",
            })
        }
    }
}

🍎抽离出来删除方法

javascript 复制代码
// 通用删除接口
pub async fn delete_api(
    pool: &MySqlPool,
    table: &str,
    pk_field: &str,
    pk_value: i32,
) -> HttpResponse {
    let sql = format!("DELETE FROM {} WHERE {} = ?", table, pk_field);
    let result = sqlx::query(&sql)
        .bind(pk_value)
        .execute(pool)
        .await;

    match result {
        Ok(_) => HttpResponse::Ok().json(BasicResponse {
            code: 200,
            msg: "删除成功!",
        }),
        Err(e) => {
            eprintln!("数据库删除失败: {:?}", e);
            HttpResponse::InternalServerError().json(BasicResponse {
                code: 500,
                msg: "删除失败!",
            })
        }
    }
}

🍎封装使用删除方法

javascript 复制代码
// 删除用户
pub async fn delete_user(
    pool: web::Data<MySqlPool>, 
    id: web::Path<i32>
) -> HttpResponse {
    crate::common::apimethods::delete_api(
        pool.get_ref(),
        "sys_user",
        "user_id",
        *id
    ).await
}

🍎测试接口ok

javascript 复制代码
{
    "code": 200,
    "msg": "删除成功!"
}

🍎软删除

接下来我们将删除更改为软删除。正常我们项目之中都会有假删除和真删除部分

javascript 复制代码
// 通用删除接口
pub async fn delete_api(
    pool: &MySqlPool,
    table: &str,
    pk_field: &str,
    pk_value: i32,
    soft_delete: bool, // 新增参数,true=软删除,false=真删除
) -> HttpResponse {
    let sql;
    let mut query;

    if soft_delete {
        // 假删除,isDeleted 字段置为 1
        sql = format!("UPDATE {} SET isDeleted = ? WHERE {} = ?", table, pk_field);
        query = sqlx::query(&sql)
            .bind(1) // 1 表示已删除
            .bind(pk_value);
    } else {
        // 真删除
        sql = format!("DELETE FROM {} WHERE {} = ?", table, pk_field);
        query = sqlx::query(&sql)
            .bind(pk_value);
    }

    let result = query.execute(pool).await;

    match result {
        Ok(_) => HttpResponse::Ok().json(BasicResponse {
            code: 200,
            msg: "删除成功!",
        }),
        Err(e) => {
            eprintln!("数据库删除失败: {:?}", e);
            HttpResponse::InternalServerError().json(BasicResponse {
                code: 500,
                msg: "删除失败!",
            })
        }
    }
}

🍎使用软删除

javascript 复制代码
// 软删除
pub async fn delete_user(
    pool: web::Data<MySqlPool>, 
    id: web::Path<i32>
) -> HttpResponse {
    crate::common::apimethods::delete_api(
        pool.get_ref(),
        "sys_user",
        "user_id",
        *id,
        true, // 软删除,isDeleted=1
    ).await
}

🍎使用真删除

javascript 复制代码
// 通用真删除
pub async fn del_delete(
    pool: web::Data<MySqlPool>,
    id: web::Path<i32>
) -> HttpResponse {
    crate::common::apimethods::delete_api(
        pool.get_ref(),
        "sys_user",
        "user_id",
        *id,
        false, // 软删除,isDeleted=1
    ).await
}
相关推荐
北城以北88888 分钟前
ES6(二)
前端·javascript·es6
努力的白熊嗨20 分钟前
多台服务器文件共享存储
服务器·后端
调试人生的显微镜22 分钟前
CSS开发工具推荐与实战经验,让样式开发更高效、更精准
后端
朕的剑还未配妥22 分钟前
移动端触摸事件与鼠标事件的触发机制详解
前端
墨鱼鱼27 分钟前
【征文计划】Rokid JSAR 实践指南:打造沉浸式 "声动空间盒" 交互体验
前端
渣哥27 分钟前
多环境配置利器:@Profile 在 Spring 项目中的实战价值
javascript·后端·面试
东百牧码人28 分钟前
还在使用ToList太Low了
后端
携欢30 分钟前
Portswigger靶场之Exploiting a mass assignment vulnerability通关秘籍
前端·安全
缓存征服者33 分钟前
CompletableFuture并行化改造,我将接口响应时间从300ms优化到50ms
后端
什么芋泥香蕉33038 分钟前
比 Manus 还好用?这款国产 AI,让 Python 小白也能玩转编程
前端·后端