在 Rust 中处理数据库:面向初学者的 PostgreSQL 和 MongoDB
\n\nRust 是一种现代系统编程语言,因其性能和安全性而日益流行。但是如何在 Rust 中处理数据库呢?在本文中,我们将介绍如何连接两种流行的数据库管理系统:关系型 PostgreSQL 和面向文档的 MongoDB,并执行基本操作。本材料面向熟悉 Rust 基础的初学者开发者。
\n\n为什么 Rust 和数据库是一个好的组合?
\n\nRust 提供了严格的类型系统和内存安全保证,这在处理数据时尤其宝贵。C/C++ 中典型的内存访问错误在编译阶段就被消除了。此外,Rust 生态系统包含了用于与数据库交互的成熟库:用于 PostgreSQL 的 diesel 和用于 MongoDB 的官方驱动程序。
在本文中,我们将学习:
\n- \n
- 从 Rust 连接到 PostgreSQL 和 MongoDB \n
- 执行 CRUD 操作(创建、读取、更新、删除) \n
- 安全高效地处理查询结果 \n
1. 通过 Diesel 库使用 PostgreSQL
\n\nDiesel 是 Rust 的一个 ORM 和查询构建器,它在编译级别提供类型安全。首先,在 Cargo.toml 中添加依赖项:
[dependencies]\ndiesel = { version = "2.1", features = ["postgres"] }\ndotenvy = "0.15"\nserde = { version = "1.0", features = ["derive"] }\nserde_json = "1.0"\ntokio = { version = "1.0", features = ["full"] }\n\n配置连接
\n\n创建一个包含数据库 URL 的 .env 文件:
DATABASE_URL=postgres://user:password@localhost/mydb\n\n现在编写用于连接和创建表的代码:
\n\nuse diesel::prelude::*;\nuse diesel::pg::PgConnection;\nuse dotenvy::dotenv;\nuse std::env;\n\npub fn establish_connection() -> PgConnection {\n dotenv().ok();\n let database_url = env::var("DATABASE_URL")\n .expect("DATABASE_URL must be set");\n PgConnection::establish(&database_url)\n .unwrap_or_else(|_| panic!("Error connecting to {}", database_url))\n}\n\n定义模式和模型
\n\n让我们创建一个 users 表和相应的 Rust 模型:
// schema.rs\ntable! {\n users (id) {\n id -> Int4,\n name -> Varchar,\n email -> Varchar,\n created_at -> Timestamp,\n }\n}\n\n// models.rs\n#[derive(Queryable, Selectable)]\n#[diesel(table_name = crate::schema::users)]\n#[diesel(check_for_backend(diesel::pg::Pg))]\npub struct User {\n pub id: i32,\n pub name: String,\n pub email: String,\n pub created_at: chrono::NaiveDateTime,\n}\n\n#[derive(Insertable)]\n#[diesel(table_name = crate::schema::users)]\npub struct NewUser {\n pub name: String,\n pub email: String,\n}\n\nCRUD 操作
\n\n创建和读取用户的示例:
\n\nuse crate::models::{User, NewUser};\nuse crate::schema::users;\n\npub fn create_user(conn: &mut PgConnection, name: &str, email: &str) -> User {\n let new_user = NewUser {\n name: name.to_string(),\n email: email.to_string(),\n };\n\n diesel::insert_into(users::table)\n .values(&new_user)\n .returning(User::as_returning())\n .get_result(conn)\n .expect("Error saving new user")\n}\n\npub fn get_all_users(conn: &mut PgConnection) -> Vec {\n users::table\n .load::(conn)\n .expect("Error loading users")\n} \n\n如您所见,Diesel 在编译阶段检查类型和列名。字段名称错误将导致编译错误,而不是运行时故障。
\n\n2. 通过官方驱动程序使用 MongoDB
\n\nMongoDB 是一种 NoSQL 数据库,以类似 JSON 的格式存储数据