Rust异步数据库连接池async-bb8-diesel的使用:支持PostgreSQL、MySQL和SQLite的高效ORM操作

Rust异步数据库连接池async-bb8-diesel的使用:支持PostgreSQL、MySQL和SQLite的高效ORM操作

安装

在项目目录中运行以下Cargo命令:

cargo add async-bb8-diesel

或者在Cargo.toml中添加以下行:

async-bb8-diesel = "0.2.1"

使用示例

以下是一个完整的异步数据库连接池使用示例,支持PostgreSQL、MySQL和SQLite:

use async_bb8_diesel::AsyncRunQueryDsl;
use diesel::prelude::*;
use async_bb8_diesel::ConnectionManager;

// 定义表结构
table! {
    users (id) {
        id -> Integer,
        name -> Text,
    }
}

#[tokio::main]
async fn main() {
    // 创建PostgreSQL连接池
    let database_url = "postgres://username:password@localhost/database_name";
    let manager = ConnectionManager::<PgConnection>::new(database_url);
    let pool = bb8::Pool::builder().build(manager).await.unwrap();

    // 获取连接
    let conn = pool.get().await.unwrap();
    
    // 异步查询
    let users: Vec<(i32, String)> = users::table
        .select((users::id, users::name))
        .load_async::<(i32, String)>(&*conn)
        .await
        .unwrap();
        
    println!("Users: {:?}", users);
}

支持多种数据库

PostgreSQL示例

use async_bb8_diesel::AsyncRunQueryDsl;
use diesel::pg::PgConnection;

let manager = ConnectionManager::<PgConnection>::new("postgres://user:pass@localhost/db");
let pool = bb8::Pool::builder().build(manager).await.unwrap();

MySQL示例

use async_bb8_diesel::AsyncRunQueryDsl;
use diesel::mysql::MysqlConnection;

let manager = ConnectionManager::<MysqlConnection>::new("mysql://user:pass@localhost/db");
let pool = bb8::Pool::builder().build(manager).await.unwrap();

SQLite示例

use async_bb8_diesel::AsyncRunQueryDsl;
use diesel::sqlite::SqliteConnection;

let manager = ConnectionManager::<SqliteConnection>::new("db.sqlite");
let pool = bb8::Pool::builder().build(manager).await.unwrap();

特性

  1. 完全异步的Diesel ORM操作
  2. 基于bb8的高效连接池管理
  3. 支持PostgreSQL、MySQL和SQLite三种数据库
  4. 与Diesel现有查询无缝集成

完整示例代码

以下是一个完整的PostgreSQL使用示例,包含连接池创建、查询和插入操作:

use async_bb8_diesel::AsyncRunQueryDsl;
use diesel::prelude::*;
use async_bb8_diesel::ConnectionManager;
use diesel::insert_into;

// 定义表结构
table! {
    users (id) {
        id -> Integer,
        name -> Text,
        email -> Text,
    }
}

#[tokio::main]
async fn main() {
    // 1. 创建PostgreSQL连接池
    let database_url = "postgres://username:password@localhost/database_name";
    let manager = ConnectionManager::<PgConnection>::new(database_url);
    let pool = bb8::Pool::builder()
        .max_size(15)  // 设置最大连接数
        .build(manager)
        .await
        .unwrap();

    // 2. 获取连接
    let conn = pool.get().await.unwrap();
    
    // 3. 创建表 (仅演示用,实际应用中表应该已存在)
    diesel::sql_query(
        "CREATE TABLE IF NOT EXISTS users (
            id SERIAL PRIMARY KEY,
            name TEXT NOT NULL,
            email TEXT NOT NULL
        )")
        .execute_async(&*conn)
        .await
        .unwrap();

    // 4. 插入数据
    let new_user = (name = "Alice", email = "alice@example.com");
    insert_into(users::table)
        .values(&new_user)
        .execute_async(&*conn)
        .await
        .unwrap();

    // 5. 查询数据
    let results: Vec<(i32, String, String)> = users::table
        .select((users::id, users::name, users::email))
        .load_async(&*conn)
        .await
        .unwrap();
        
    println!("查询结果:");
    for user in results {
        println!("ID: {}, 姓名: {}, 邮箱: {}", user.0, user.1, user.2);
    }

    // 6. 带条件的查询
    let alice: Vec<(i32, String, String)> = users::table
        .filter(users::name.eq("Alice"))
        .select((users::id, users::name, users::email))
        .load_async(&*conn)
        .await
        .unwrap();
        
    println!("查询Alice的结果: {:?}", alice);
}

1 回复

Rust异步数据库连接池async-bb8-diesel的使用

完整示例代码

下面是一个完整的PostgreSQL数据库操作示例,包含连接池创建、查询和事务处理:

use async_bb8_diesel::AsyncRunQueryDsl;
use async_bb8_diesel::ConnectionManager;
use diesel::{prelude::*, insert_into};
use std::time::Duration;

// 定义schema.rs中的表结构
mod schema {
    table! {
        users (id) {
            id -> Int4,
            name -> Varchar,
            email -> Varchar,
        }
    }
}

// 定义User模型
#[derive(Queryable, Debug)]
struct User {
    id: i32,
    name: String,
    email: String,
}

// 定义NewUser结构用于插入
#[derive(Insertable)]
#[diesel(table_name = schema::users)]
struct NewUser {
    name: String,
    email: String,
}

#[tokio::main]
async fn main() {
    // 1. 创建连接池
    let database_url = "postgres://username:password@localhost/database";
    let manager = ConnectionManager::<PgConnection>::new(database_url);
    
    let pool = bb8::Pool::builder()
        .max_size(15)
        .min_idle(Some(5))
        .connection_timeout(Duration::from_secs(30))
        .build(manager)
        .await
        .unwrap();

    // 2. 执行查询示例
    let users = get_users(&pool).await;
    println!("查询到的用户: {:?}", users);

    // 3. 事务处理示例
    let new_user = NewUser {
        name: "张三".to_string(),
        email: "zhangsan@example.com".to_string(),
    };
    
    match create_user(&pool, new_user).await {
        Ok(user) => println!("创建的用户: {:?}", user),
        Err(e) => eprintln!("创建用户失败: {}", e),
    }
}

// 查询用户函数
async fn get_users(pool: &bb8::Pool<ConnectionManager<PgConnection>>) -> Vec<User> {
    use schema::users::dsl::*;
    
    let conn = pool.get().await.unwrap();
    
    users
        .limit(10)
        .load_async::<User>(&conn)
        .await
        .unwrap()
}

// 创建用户函数(带事务)
async fn create_user(
    pool: &bb8::Pool<ConnectionManager<PgConnection>>,
    new_user: NewUser,
) -> Result<User, diesel::result::Error> {
    use schema::users;
    
    let conn = pool.get().await.unwrap();
    
    conn.transaction_async(|conn| async move {
        insert_into(users::table)
            .values(&new_user)
            .get_result_async(conn)
            .await
    })
    .await
}

代码说明

  1. 依赖配置

    • 需要添加async-bb8-dieseltokiodiesel依赖
    • 根据数据库类型选择对应的feature
  2. 模型定义

    • 使用Queryable派生宏定义查询模型
    • 使用Insertable派生宏定义插入模型
  3. 连接池管理

    • 使用ConnectionManager创建特定数据库的连接管理器
    • 使用bb8::Pool构建连接池,配置连接数参数
  4. 异步查询

    • 使用load_async执行异步查询
    • 使用get_result_async获取单条结果
  5. 事务处理

    • 使用transaction_async执行异步事务
    • 事务内可以执行多个数据库操作

实际应用建议

  1. 将数据库配置提取到环境变量或配置文件中
  2. 为不同的数据库操作创建单独的模块
  3. 添加适当的错误处理和日志记录
  4. 考虑实现连接池的健康检查

这个完整示例展示了如何使用async-bb8-diesel进行常见的数据库操作,您可以根据实际需求进行调整和扩展。

回到顶部