Diesel:Rust 语言的编译时安全 ORM
Diesel:Rust 语言的编译时安全 ORM
用 Rust 写数据库交互代码,最怕什么?SQL 写错了,跑起来才发现。
Diesel 解决了这个问题。它是 Rust 生态中最成熟的 ORM 和查询构建器,星标超过 14,000。所有 SQL 在编译阶段就会被检查,类型不对直接报错,不会留到运行时。

支持三种数据库:PostgreSQL、MySQL、SQLite。

安装
在 Cargo.toml 中加上依赖:
[dependencies]
diesel = { version = "2.2", features = ["postgres"] }
features 改成 mysql 或 sqlite 即可切换后端。
基本查询
查全部用户:
users::table.load(&mut connection)
对应生成的 SQL 是 SELECT * FROM users;。
按关联关系查询,比如查某个用户的所有文章:
Post::belonging_to(user).load(&mut connection)
生成 SQL:SELECT * FROM posts WHERE user_id = 1;。
组合条件查询
嵌套查询、过滤、排序、分页,可以自由组合:
let versions = Version::belonging_to(krate)
.select(id)
.order(num.desc())
.limit(5);
let downloads = version_downloads
.filter(date.gt(now - 90.days()))
.filter(version_id.eq_any(versions))
.order(date)
.load::<Download>(&mut conn)?;
这段代码生成的 SQL 包含子查询和日期过滤,全部在编译时完成类型校验。
减少样板代码
Diesel 通过 derive 宏自动生成字段映射:
#[derive(Queryable, Selectable)]
#[diesel(table_name = downloads)]
pub struct Download {
id: i32,
version_id: i32,
downloads: i32,
date: SystemTime,
}
不用 Diesel 的话,你得手动实现一个 from_row 方法,逐字段调用 row.get("xxx"),写起来繁琐且容易出错。
插入数据
定义一个结构体,用 Insertable 标注,直接插入:
#[derive(Insertable)]
#[diesel(table_name = users)]
struct NewUser<'a> {
name: &'a str,
hair_color: Option<&'a str>,
}
insert_into(users)
.values(&new_users)
.execute(&mut connection);
把 execute 换成 get_results,还能直接拿到插入后的完整记录。
更新数据
单条修改用 save_changes,批量更新用 update 加过滤条件:
// 单条
post.published = true;
post.save_changes(&mut connection);
// 批量
update(users.filter(email.like("%@spammer.com")))
.set(banned.eq(true))
.execute(&mut connection)
原生 SQL
遇到复杂查询写不成构建器语法时,也可以直接写 SQL,通过 sql_query 调用,结果同样映射到结构体。
整体来看,Diesel 的核心价值很清晰:让 Rust 的类型系统帮你在编译阶段就把 SQL 问题拦住,同时省掉大量手动映射的样板代码。对于长期维护的项目来说,这个 compile-time 的保障比写起来方便更重要。
体。
整体来看,Diesel 的核心价值很清晰:让 Rust 的类型系统帮你在编译阶段就把 SQL 问题拦住,同时省掉大量手动映射的样板代码。对于长期维护的项目来说,这个 compile-time 的保障比写起来方便更重要。
所有评论(0)