Bolo  当前访客:1 管理登录

日常点滴记忆

一任群芳妒,无边丝雨细。 蓬莱此去无多路,青鸟殷勤为探看。

用rust编写一个单例连接mysql数据库的公用类,实现功能要包含自动连接数据库,自动检查连接是否断开如果断开自动重连,异常处理,对数据表的增删改查

2023-12-07/2023-12-07 fogsun
0  评论    359  浏览

以下是一个用Rust编写的单例类示例,用于连接MySQL数据库并实现对数据表的增删改查操作。代码使用了 mysqlr2d2 crate 来连接和管理连接池,以及 anyhow crate 来处理异常。请确保在使用之前,在 Cargo.toml 文件中添加相应的依赖。

use std::sync::Mutex;
use r2d2::Pool;
use r2d2_mysql::mysql::{self, Opts};
use r2d2_mysql::MysqlConnectionManager;
use anyhow::{Result, Context};

#[derive(Clone)]
pub struct DatabaseConnection {
    pool: Pool<MysqlConnectionManager>,
}

impl DatabaseConnection {
    fn new() -> Result<Self> {
        let manager = MysqlConnectionManager::new(Opts::default());
        let pool = Pool::builder()
            .max_size(10)
            .build(manager)?;
        Ok(Self { pool })
    }

    fn get_connection(&self) -> Result<mysql::PooledConn> {
        self.pool.get().context("Failed to get database connection")
    }

    pub fn execute_update(&self, query: &str, args: &[&dyn mysql::ToValue]) -> Result<()> {
        let conn = self.get_connection()?;
        conn.prep_exec(query, args)?;
        Ok(())
    }

    pub fn execute_query(&self, query: &str, args: &[&dyn mysql::ToValue]) -> Result<Vec<mysql::Row>> {
        let conn = self.get_connection()?;
        let result = conn.prep_exec(query, args)?;
        let rows = result.map(|x| x.unwrap()).collect();
        Ok(rows)
    }
}

impl Default for DatabaseConnection {
    fn default() -> Self {
        Self::new().expect("Failed to initialize database connection")
    }
}

lazy_static::lazy_static! {
    static ref DB_CONNECTION: Mutex<DatabaseConnection> = Mutex::new(DatabaseConnection::default());
}

pub fn get_instance() -> Result<&'static DatabaseConnection> {
    DB_CONNECTION.lock().map_err(|e| anyhow::Error::from(e))
}

fn main() -> Result<()> {
    let db = get_instance()?;

    // 示例:插入数据
    db.execute_update("INSERT INTO users (name, age) VALUES (?, ?)", &[&"John Doe", &30])?;

    // 示例:更新数据
    db.execute_update("UPDATE users SET age = ? WHERE name = ?", &[&31, &"John Doe"])?;

    // 示例:查询数据
    let rows = db.execute_query("SELECT name, age FROM users WHERE age > ?", &[&30])?;
    for row in rows {
        let (name, age) = mysql::from_row(row);
        println!("Name: {}, Age: {}", name, age);
    }

    // 示例:删除数据
    db.execute_update("DELETE FROM users WHERE name = ?", &[&"John Doe"])?;

    Ok(())
}

在上述示例中,DatabaseConnection 结构体是一个单例类,使用 lazy_static crate 来确保只有一个实例。通过 get_instance 函数获取实例。在 new 方法中创建连接池,通过 execute_update 方法执行增删改语句,通过 execute_query 方法执行查询语句。示例代码演示了插入数据、更新数据、查询数据以及删除数据的使用。你可以根据自己的需求进行相应的修改和扩展。请确保在连接数据库时提供正确的连接参数。


标题:用rust编写一个单例连接mysql数据库的公用类,实现功能要包含自动连接数据库,自动检查连接是否断开如果断开自动重连,异常处理,对数据表的增删改查
作者:fogsun
地址:HTTPS://nb500.cn/articles/2023/12/07/1701916329862.html

TOP