使用Rust和Diesel ORM创建SQLite CRUD应用

说明:

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

打开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
----------
相关推荐
权^16 分钟前
MySQL--聚合查询、联合查询、子查询、合并查询(上万字超详解!!!)
大数据·数据库·学习·mysql
碳苯28 分钟前
【rCore OS 开源操作系统】Rust 枚举与模式匹配
开发语言·人工智能·后端·rust·操作系统·os
Code成立1 小时前
1、深入理解Redis线程模型
数据库·redis·bootstrap
缘友一世3 小时前
macos安装mongodb
数据库·mongodb·macos
zaim13 小时前
计算机的错误计算(一百一十四)
java·c++·python·rust·go·c·多项式
万事大吉CC4 小时前
mysql单表查询·3
数据库·mysql
bin91535 小时前
【EXCEL数据处理】000010 案列 EXCEL文本型和常规型转换。使用的软件是微软的Excel操作的。处理数据的目的是让数据更直观的显示出来,方便查看。
大数据·数据库·信息可视化·数据挖掘·数据分析·excel·数据可视化
Miqiuha5 小时前
lock_guard和unique_lock学习总结
java·数据库·学习
一 乐6 小时前
学籍管理平台|在线学籍管理平台系统|基于Springboot+VUE的在线学籍管理平台系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习
Java探秘者10 小时前
Maven下载、安装与环境配置详解:从零开始搭建高效Java开发环境
java·开发语言·数据库·spring boot·spring cloud·maven·idea