Rust-用户模块CRUD
👉用户搜索
🍎routes.rs
在入口文件之中导入对应模块,上面我们已经导入了,然后在这里我们编写我们想要的对应接口
注册路由,集中管理接口路径映射
javascript
use actix_web::web;
pub fn config(cfg: &mut web::ServiceConfig) {
cfg.route("/users", web::get().to(crate::modules::user::handlers::get_all_users));
}
🍎handlers.rs
在这里我们编写对应的查询接口的逻辑,这里我们直接拿数据库的查询语言来写
javascript
// # 处理函数(可选)
use actix_web::{web, HttpResponse, Responder};
use sqlx::MySqlPool;
use crate::modules::user::models::User;
pub async fn get_all_users(pool: web::Data<MySqlPool>) -> impl Responder {
let users = sqlx::query_as::<_, User>("SELECT * FROM sys_user")
.fetch_all(pool.get_ref())
.await;
match users {
Ok(list) => HttpResponse::Ok().json(list),
Err(e) => {
eprintln!("数据库查询失败: {:?}", e);
HttpResponse::InternalServerError().body("数据库查询失败")
}
}
}
这个时候我们重新运行以后就可以查看,这个时候已经给我们返回了下面的查询内容了
javascript
http://127.0.0.1:8080/api/users
[{"id":1,"name":"太白1","email":"zhangsan@example.com"},
{"id":2,"name":"李太白1","email":"lisi@example.com"},
{"id":3,"name":"王太白1","email":"wangwu@example.com"}
]
用户搜索ok
👉新增用户
🍎引入路由接口
javascript
cfg.route("/system/users", web::post()
.to(crate::modules::user::handlers::post_add_users));
🍎定义新增类型数据
javascript
// 添加用户接口返回值
#[derive(Deserialize)]
pub struct AddUserRequest {
pub username: String, // 用户名
pub password: String, // 密码
pub age: String,
pub address: String,
pub sex: i32,
pub phone: String,
pub disease: String,
pub name: String // 姓名
}
🍎新增用户接口
javascript
// 新增用户
pub async fn post_add_users(
pool: web::Data<MySqlPool>,
form: web::Json<AddUserRequest>,
) -> HttpResponse {
// 1. 检查用户名是否已存在
let exists: (i64,) = match sqlx::query_as("SELECT COUNT(*) FROM sys_user WHERE username = ?")
.bind(&form.username)
.fetch_one(pool.get_ref())
.await
{
Ok(count) => count,
Err(_) => {
return HttpResponse::InternalServerError().json(ApiResponse {
code: 500,
msg: "数据库错误",
data: None::<()>,
})
}
};
if exists.0 > 0 {
return HttpResponse::Ok().json(ApiResponse {
code: 400,
msg: "用户名已存在",
data: None::<()>,
});
}
// 2. 密码加密
let hashed_pwd = match hash(&form.password, DEFAULT_COST) {
Ok(pwd) => pwd,
Err(_) => {
return HttpResponse::InternalServerError().json(ApiResponse {
code: 500,
msg: "密码加密失败",
data: None::<()>,
})
}
};
// 3. 插入新用户
// 插入新用户
let result = sqlx::query(
"INSERT INTO sys_user (username,password, age, address, sex, phone,disease,name) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
)
.bind(&form.username)
.bind(&hashed_pwd)
.bind(&form.age)
.bind(&form.address)
.bind(form.sex)
.bind(&form.phone)
.bind(&form.disease)
.bind(&form.name)
.execute(pool.get_ref())
.await;
match result {
Ok(_) => HttpResponse::Ok().json(ApiResponse {
code: 200,
msg: "新增用户成功",
data: None::<()>,
}),
Err(e) => {
eprintln!("新增用户失败: {:?}", e);
HttpResponse::InternalServerError().json(ApiResponse {
code: 500,
msg: "新增用户失败",
data: None::<()>,
})
}
}
}
这里可以看到我们数据都写的比较简单,后面我们依然是需要将接口进行筛选和进一步封装,这里先拿最原始的去完成,先实现功能为主。
🍎 测试接口
javascript
{
"code": 200,
"msg": "新增用户成功"
}
👉查询用户详情
🍎routes.rs
接下来开始查询用户的详情,依然是我们路由的部分去进行添加
javascript
cfg.route("/system/users/{id}",
web::get().to(crate::modules::user::handlers::get_user_detail));
🍎定义一下详情数据格式
javascript
// 详情数据接口
#[derive(Serialize)]
pub struct ApiDetailResponse<T> {
pub code: i32,
pub msg: &'static str,
pub data: T,
}
🍎编写逻辑handlers.rs
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
{
"code": 200,
"msg": "查询成功",
"data": {
"userId": 44,
"username": "666666",
"password": "666666",
"age": "666666",
"name": "san",
"sex": 1,
"address": "666666",
"state": null,
"phone": "18735797977",
"avatar": "/uploads/images/17ng",
"user_height": null,
"user_weight": null,
"disease": "18735797977"
}
}
👉用户更新
🍎routes.rs
接下来开始添加用户的接口路由,依然是我们路由的部分去进行添加
javascript
cfg.route("/system/users",
web::put().to(crate::modules::user::handlers::put_update_users));
🍎编写逻辑handlers.rs
这里卡住了有段时间,我们采用一个比较简单的写法尝试,在卡柱的时候,越简单的代码反而越容易越过去,从简单开始。
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
{
"code": 200,
"msg": "更新成功!"
}
更新年龄就成功了
👉用户删除
🍎routes.rs
接下来开始查询用户的详情,依然是我们路由的部分去进行添加
javascript
cfg.route("/system/users/{id}",
web::delete().to(crate::modules::user::handlers::delete_one_users));
🍎编写逻辑handlers.rs
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(Response {
code: 200,
msg: "删除成功!".to_string(),
}),
Err(e) => {
eprintln!("数据库删除失败: {:?}", e);
HttpResponse::InternalServerError().json(Response {
code: 500,
msg: "删除失败!".to_string(),
})
}
}
}
尝试一下我们的功能
javascript
{
"code": 200,
"msg": "删除成功!"
}
删除功能ok