说明:
- 系统:Windows 11 专业版 23H2
- Rust:v1.78.0
- diesel:最新版本v2.1.6
- 完整代码已更新到Github(https://github.com/VinciYan/diesel_sqlite.git)
- 安装Rust可以参考之前写的Rust最新版安装(v1.78.0+)
plaintext
cargo install diesel_cli --no-default-features --features "sqlite-bundled"
新建项目
plaintext
cargo new diesel_sqlite
cd .\diesel_sqlite\
打开"Cargo.toml",修改为
toml
[package]
name = "diesel_sqlite"
version = "0.1.0"
edition = "2021"
[dependencies]
diesel = { version = "2.1.6", features = ["sqlite", "r2d2"] }
dotenv = "0.15.0"
rusqlite = { version = "0.31.0", features = ["bundled"] }
新建".env"文件
plaintext
DATABASE_URL=crud.db
plaintext
PS > diesel setup
Creating migrations directory at: C:\Users\sywq6\Downloads\diesel_sqlite\diesel_sqlite\migrations
Creating database: crud.db
此时项目文件包括如下:
plaintext
│ .env
│ .gitignore
│ Cargo.toml
│ crud.db
│ diesel.toml
│
├─migrations
│ .keep
│
└─src
main.rs
plaintext
PS > diesel migration generate create_users
Creating migrations\2024-05-23-142433_create_users\up.sql
Creating migrations\2024-05-23-142433_create_users\down.sql
这条命令生成了用于创建和删除users表的迁移文件。此时项目文件包括如下(新增down.sql和up.sql):
plaintext
│ .env
│ .gitignore
│ Cargo.toml
│ crud.db
│ diesel.toml
│
├─migrations
│ │ .keep
│ │
│ └─2024-05-23-142433_create_users
│ down.sql
│ up.sql
│
└─src
main.rs
修改"up.sql"文件
sql
-- Your SQL goes here
CREATE TABLE "users" (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
address TEXT NOT NULL,
date_created TEXT NOT NULL
);
INSERT INTO
"users"(name, address, date_created)
VALUES
("Ian", "11 Apple Street", "Today");
修改"down.sql"文件
sql
-- This file should undo anything in `up.sql`
DROP TABLE users;
sql
PS > diesel migration run
Running migration 2024-05-23-142433_create_users
此时项目文件包括如下(新增schema.rs):
sql
│ .env
│ .gitignore
│ Cargo.toml
│ crud.db
│ diesel.toml
│
├─migrations
│ │ .keep
│ │
│ └─2024-05-23-142433_create_users
│ down.sql
│ up.sql
│
└─src
main.rs
schema.rs
rust
// @generated automatically by Diesel CLI.
diesel::table! {
users (id) {
id -> Nullable<Integer>,
name -> Text,
address -> Text,
date_created -> Text,
}
}
新建"src/models.rs"文件,这个文件定义了User结构体,用于查询结果的映射。
rust
use diesel::{Queryable, Insertable};
use crate::schema::users;
#[derive(Debug, Queryable, Selectable)]
pub struct User {
pub id: Option<i32>,
pub name: String,
pub address: String,
pub date_created: String,
}
#[derive(Debug, Insertable)]
#[table_name = "users"]
pub struct NewUser<'a> {
pub name: &'a str,
pub address: &'a str,
pub date_created: &'a str,
}
修改"src/main.rs"文件
rust
#[macro_use]
extern crate diesel;
mod schema;
mod models;
use diesel::r2d2::{self, ConnectionManager};
use diesel::prelude::*;
use diesel::SqliteConnection;
use dotenv::dotenv;
use std::env;
use crate::schema::users::dsl::*;
use crate::models::User;
use crate::models::NewUser;
use diesel::insert_into;
use std::error::Error;
pub type Pool = r2d2::Pool<ConnectionManager<SqliteConnection>>;
fn insert_user(pool: &Pool, new_user: NewUser) -> Result<usize, Box<dyn Error>> {
let mut db_connection = pool.get()?;
insert_into(users).values(&new_user).execute(&mut db_connection).map_err(|e| e.into())
}
fn delete_user_by_name(pool: &Pool, user_name: &str) -> Result<usize, Box<dyn Error>> {
let mut db_connection = pool.get()?;
diesel::delete(users.filter(name.eq(user_name)))
.execute(&mut db_connection)
.map_err(|e| e.into())
}
fn main() {
dotenv().ok();
// 从环境变量读取数据库 URL
let database_url = env::var("DATABASE_URL").unwrap_or_else(|_| {
eprintln!("DATABASE_URL not found");
std::process::exit(1);
});
// 创建数据库连接池
let database_pool = Pool::builder()
.build(ConnectionManager::new(database_url))
.expect("Failed to create pool.");
// 获取一个数据库连接
let mut db_connection = database_pool.get().expect("Failed to get a connection from the pool.");
// 插入新用户数据
let new_user = NewUser {
name: "Alice",
address: "22 Orange Avenue",
date_created: "Today",
};
match insert_user(&database_pool, new_user) {
Ok(_) => println!("New user inserted successfully"),
Err(err) => eprintln!("Error inserting new user: {}", err),
}
// 查询所有用户
match users.load::<User>(&mut db_connection) {
Ok(results) => {
println!("Displaying {} users", results.len());
for user in results {
match user.id {
Some(user_id) => println!("ID: {}", user_id), // 使用新的变量名称
None => println!("ID: None"),
}
println!("Name: {}", user.name);
println!("Address: {}", user.address);
println!("Date Created: {}", user.date_created);
println!("----------\n");
}
},
Err(err) => {
eprintln!("Error loading users: {}", err);
},
}
// 删除用户
let user_name_to_delete = "Alice";
match delete_user_by_name(&database_pool, user_name_to_delete) {
Ok(count) => println!("Deleted {} users with name '{}'", count, user_name_to_delete),
Err(err) => eprintln!("Error deleting user: {}", err),
}
// 再次查询所有用户
match users.load::<User>(&mut db_connection) {
Ok(results) => {
println!("Displaying {} users", results.len());
for user in results {
match user.id {
Some(user_id) => println!("ID: {}", user_id), // 使用新的变量名称
None => println!("ID: None"),
}
println!("Name: {}", user.name);
println!("Address: {}", user.address);
println!("Date Created: {}", user.date_created);
println!("----------\n");
}
},
Err(err) => {
eprintln!("Error loading users: {}", err);
},
}
}
运行代码:
rust
PS > cargo run
...
Running `target\debug\diesel_sqlite.exe`
New user inserted successfully
Displaying 2 users
ID: 1
Name: Ian
Address: 11 Apple Street
Date Created: Today
----------
ID: 4
Name: Alice
Address: 22 Orange Avenue
Date Created: Today
----------
Deleted 1 users with name 'Alice'
Displaying 1 users
ID: 1
Name: Ian
Address: 11 Apple Street
Date Created: Today
----------