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
| 维度 | Diesel | SQLx |
|---|---|---|
| 查询方式 | 类型安全 DSL | 原始 SQL |
| 异步 | ❌ 同步 | ✅ 异步 |
| 编译时检查 | Schema 类型 | SQL 语法 |
| 学习曲线 | 中等 | 低 |
| 灵活性 | 中(复杂 SQL 需 sql_query) | 高 |
常见面试问题
Q1: Diesel 为什么选择同步设计?
答案:
Diesel 的设计理念是通过类型系统在编译时保证查询正确性。异步 trait 在早期 Rust 中不够成熟,且数据库查询通常很快(毫秒级),同步模型足够。可用 tokio::task::spawn_blocking 在异步环境中使用 Diesel。
不过 Diesel 也推出了 diesel-async 实验性支持。