Rust如何操作数据库
刚开始学习Rust,想用Rust连接和操作数据库,但不知道从何下手。请问有哪些常用的Rust数据库操作库推荐?比如MySQL或PostgreSQL该怎么连接?需要特别注意哪些Rust特有的并发安全或所有权问题吗?能否给个简单的CRUD示例代码?最好能对比下不同库的优缺点,比如diesel和sqlx哪个更适合新手入门?
2 回复
Rust操作数据库主要通过第三方库实现:
- Diesel:最流行的ORM,支持PostgreSQL、MySQL、SQLite
- SQLx:异步数据库驱动,支持多种数据库
- SeaORM:新兴的异步ORM
安装依赖后,配置数据库连接,即可执行查询和事务操作。
在Rust中操作数据库,主要通过以下几个步骤实现:
1. 选择数据库驱动
根据数据库类型选择相应的Rust库:
PostgreSQL
// Cargo.toml
// [dependencies]
// tokio-postgres = "0.7"
// postgres-native-tls = "0.5"
use tokio_postgres::{NoTls, Error};
#[tokio::main]
async fn main() -> Result<(), Error> {
let (client, connection) = tokio_postgres::connect(
"host=localhost user=postgres password=123456 dbname=test",
NoTls,
).await?;
tokio::spawn(async move {
if let Err(e) = connection.await {
eprintln!("connection error: {}", e);
}
});
// 执行查询
let rows = client
.query("SELECT id, name FROM users WHERE id = $1", &[&1i32])
.await?;
for row in rows {
let id: i32 = row.get(0);
let name: &str = row.get(1);
println!("id: {}, name: {}", id, name);
}
Ok(())
}
MySQL
// Cargo.toml
// [dependencies]
// mysql = "*"
use mysql::*;
use mysql::prelude::*;
fn main() -> Result<()> {
let url = "mysql://username:password@localhost:3306/database";
let pool = Pool::new(url)?;
let mut conn = pool.get_conn()?;
// 查询数据
let users: Vec<(i32, String)> = conn
.query_map("SELECT id, name FROM users", |(id, name)| (id, name))?;
for (id, name) in users {
println!("id: {}, name: {}", id, name);
}
// 插入数据
conn.exec_drop(
"INSERT INTO users (name) VALUES (?)",
("Alice",),
)?;
Ok(())
}
2. 使用ORM框架(推荐)
Diesel(最流行的Rust ORM)
// Cargo.toml
// [dependencies]
// diesel = { version = "2.0", features = ["postgres"] }
// dotenvy = "0.15"
use diesel::prelude::*;
use diesel::pg::PgConnection;
use dotenvy::dotenv;
use std::env;
pub fn establish_connection() -> PgConnection {
dotenv().ok();
let database_url = env::var("DATABASE_URL")
.expect("DATABASE_URL must be set");
PgConnection::establish(&database_url)
.expect(&format!("Error connecting to {}", database_url))
}
// 定义模型
#[derive(Queryable)]
struct User {
pub id: i32,
pub name: String,
pub email: String,
}
// 查询示例
fn get_users() -> Vec<User> {
use crate::schema::users::dsl::*;
let connection = &mut establish_connection();
users
.filter(email.like("%@example.com%"))
.limit(10)
.load::<User>(connection)
.expect("Error loading users")
}
3. 异步操作
对于异步应用,可以使用sqlx:
// Cargo.toml
// [dependencies]
// sqlx = { version = "0.7", features = ["postgres", "runtime-tokio-rustls"] }
// tokio = { version = "1", features = ["full"] }
use sqlx::postgres::PgPoolOptions;
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
let pool = PgPoolOptions::new()
.connect("postgres://user:pass@localhost/db")
.await?;
let row: (i64,) = sqlx::query_as("SELECT $1")
.bind(150_i64)
.fetch_one(&pool)
.await?;
assert_eq!(row.0, 150);
Ok(())
}
主要库推荐
- Diesel: 功能完整的ORM,编译时检查查询
- sqlx: 异步数据库工具包,零开销
- tokio-postgres: PostgreSQL的异步客户端
- mysql: MySQL客户端
- rusqlite: SQLite客户端
选择哪个库取决于你的具体需求:需要完整ORM功能选Diesel,需要异步支持选sqlx,简单项目可选直接使用数据库客户端。

