Diesel 集成 #
添加依赖 #
toml
[dependencies]
diesel = { version = "2", features = ["postgres", "r2d2", "chrono"] }
dotenvy = "0.15"
[dependencies.actix-web]
version = "4"
配置 #
安装 Diesel CLI #
bash
cargo install diesel_cli --no-default-features --features postgres
初始化 #
bash
diesel setup
diesel migration generate create_users
数据库连接 #
rust
use diesel::pg::PgConnection;
use diesel::r2d2::{self, ConnectionManager};
use std::env;
pub type DbPool = r2d2::Pool<ConnectionManager<PgConnection>>;
pub fn establish_connection() -> DbPool {
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let manager = ConnectionManager::<PgConnection>::new(database_url);
r2d2::Pool::builder()
.build(manager)
.expect("Failed to create pool.")
}
模型定义 #
Schema #
rust
diesel::table! {
users (id) {
id -> Int4,
name -> Varchar,
email -> Varchar,
created_at -> Timestamp,
}
}
Model #
rust
use chrono::NaiveDateTime;
use diesel::prelude::*;
#[derive(Queryable, Selectable, Debug, Clone)]
#[diesel(table_name = crate::schema::users)]
pub struct User {
pub id: i32,
pub name: String,
pub email: String,
pub created_at: NaiveDateTime,
}
#[derive(Insertable)]
#[diesel(table_name = crate::schema::users)]
pub struct NewUser<'a> {
pub name: &'a str,
pub email: &'a str,
}
CRUD 操作 #
创建 #
rust
use crate::schema::users;
use diesel::prelude::*;
pub fn create_user(conn: &mut PgConnection, name: &str, email: &str) -> QueryResult<User> {
let new_user = NewUser { name, email };
diesel::insert_into(users::table)
.values(&new_user)
.returning(User::as_returning())
.get_result(conn)
}
查询 #
rust
pub fn get_all_users(conn: &mut PgConnection) -> QueryResult<Vec<User>> {
users::table
.select(User::as_select())
.load(conn)
}
pub fn get_user_by_id(conn: &mut PgConnection, user_id: i32) -> QueryResult<Option<User>> {
users::table
.find(user_id)
.select(User::as_select())
.first(conn)
.optional()
}
更新 #
rust
pub fn update_user(
conn: &mut PgConnection,
user_id: i32,
name: Option<&str>,
email: Option<&str>,
) -> QueryResult<User> {
diesel::update(users::find(users::table, user_id))
.set((
users::name.eq(name.unwrap_or_default()),
users::email.eq(email.unwrap_or_default()),
))
.returning(User::as_returning())
.get_result(conn)
}
删除 #
rust
pub fn delete_user(conn: &mut PgConnection, user_id: i32) -> QueryResult<usize> {
diesel::delete(users::find(users::table, user_id))
.execute(conn)
}
在 Actix Web 中使用 #
rust
use actix_web::{web, App, HttpResponse, HttpServer, Responder};
use diesel::prelude::*;
async fn list_users(pool: web::Data<DbPool>) -> impl Responder {
let mut conn = pool.get().unwrap();
match get_all_users(&mut conn) {
Ok(users) => HttpResponse::Ok().json(users),
Err(_) => HttpResponse::InternalServerError().finish(),
}
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let pool = establish_connection();
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(pool.clone()))
.route("/users", web::get().to(list_users))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
下一步 #
继续学习 SQLx 集成,了解异步查询方案!
最后更新:2026-03-29