跳到主要内容

Diesel ORM

问题

Diesel 的类型安全查询是如何实现的?

答案

Diesel 是 Rust 的类型安全 ORM,通过 Rust 的类型系统在编译时保证查询正确性。

Schema 定义

src/schema.rs
// 由 diesel migration 自动生成
diesel::table! {
users (id) {
id -> Int4,
name -> Varchar,
email -> Varchar,
created_at -> Timestamp,
}
}

CRUD 操作

use diesel::prelude::*;
use crate::schema::users;

#[derive(Queryable, Selectable, Debug)]
#[diesel(table_name = users)]
struct User {
id: i32,
name: String,
email: String,
}

#[derive(Insertable)]
#[diesel(table_name = users)]
struct NewUser<'a> {
name: &'a str,
email: &'a str,
}

// 查询
fn find_user(conn: &mut PgConnection, user_id: i32) -> QueryResult<User> {
users::table
.find(user_id)
.select(User::as_select())
.first(conn)
}

// 条件查询
fn search_users(conn: &mut PgConnection, keyword: &str) -> QueryResult<Vec<User>> {
users::table
.filter(users::name.ilike(format!("%{}%", keyword)))
.order(users::created_at.desc())
.limit(20)
.select(User::as_select())
.load(conn)
}

// 插入
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)
}

Diesel vs SQLx

维度DieselSQLx
查询方式类型安全 DSL原始 SQL
异步❌ 同步✅ 异步
编译时检查Schema 类型SQL 语法
学习曲线中等
灵活性中(复杂 SQL 需 sql_query)

常见面试问题

Q1: Diesel 为什么选择同步设计?

答案

Diesel 的设计理念是通过类型系统在编译时保证查询正确性。异步 trait 在早期 Rust 中不够成熟,且数据库查询通常很快(毫秒级),同步模型足够。可用 tokio::task::spawn_blocking 在异步环境中使用 Diesel。

不过 Diesel 也推出了 diesel-async 实验性支持。

相关链接