Rust数据库连接池库deadpool-sqlite的使用:高效管理SQLite连接和异步操作
Rust数据库连接池库deadpool-sqlite的使用:高效管理SQLite连接和异步操作
Deadpool是一个简单高效的异步连接池库,用于管理各种类型的连接和对象。deadpool-sqlite是专门为SQLite数据库设计的连接池实现,它基于rusqlite库并提供了线程安全的连接管理。
特性
特性 | 描述 | 额外依赖 | 默认启用 |
---|---|---|---|
rt_tokio_1 |
支持tokio运行时 | deadpool/rt_tokio_1 |
是 |
rt_async-std_1 |
支持async-std运行时 | deadpool/rt_async-std_1 |
否 |
serde |
支持serde序列化 | deadpool/serde , serde/derive |
否 |
tracing |
支持tracing日志追踪 | deadpool-sync/tracing , tracing |
否 |
示例代码
use deadpool_sqlite::{Config, Runtime};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut cfg = Config::new("db.sqlite3");
let pool = cfg.create_pool(Runtime::Tokio1).unwrap();
let conn = pool.get().await.unwrap();
let result: i64 = conn
.interact(|conn| {
let mut stmt = conn.prepare("SELECT 1")?;
let mut rows = stmt.query([])?;
let row = rows.next()?.unwrap();
row.get(0)
})
.await??;
assert_eq!(result, 1);
Ok(())
}
完整示例Demo
use deadpool_sqlite::{Config, Runtime};
use tokio::task;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建连接池配置
let mut cfg = Config::new("example.db");
// 设置连接池大小
cfg.pool.max_size = 16;
// 创建连接池 (使用Tokio运行时)
let pool = cfg.create_pool(Runtime::Tokio1)?;
// 创建表
init_db(&pool).await?;
// 并发插入数据
let tasks: Vec<_> = (0..10)
.map(|i| {
let pool = pool.clone();
task::spawn(async move {
let conn = pool.get().await?;
conn.interact(move |conn| {
conn.execute(
"INSERT INTO users (name, age) VALUES (?1, ?2)",
[format!("User {}", i), i.to_string()],
)
})
.await?
})
})
.collect();
// 等待所有插入任务完成
for task in tasks {
task.await??;
}
// 查询数据
let conn = pool.get().await?;
let users: Vec<(String, i32)> = conn
.interact(|conn| {
let mut stmt = conn.prepare("SELECT name, age FROM users")?;
let rows = stmt.query_map([], |row| Ok((row.get(0)?, row.get(1)?)))?;
rows.collect::<Result<Vec<_>, _>>()
})
.await??;
println!("Users: {:?}", users);
Ok(())
}
async fn init_db(pool: &deadpool_sqlite::Pool) -> Result<(), Box<dyn std::error::Error>> {
let conn = pool.get().await?;
conn.interact(|conn| {
conn.execute_batch(
"BEGIN;
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER NOT NULL
);
COMMIT;",
)
})
.await??;
Ok(())
}
许可证
deadpool-sqlite采用以下任一种许可证:
- Apache License, Version 2.0
- MIT license
安装
要在项目中使用deadpool-sqlite,可以运行以下Cargo命令:
cargo add deadpool-sqlite
或者在Cargo.toml中添加:
deadpool-sqlite = "0.12.1"
这个库提供了高效的SQLite连接管理,特别适合在异步环境中使用SQLite数据库的场景。通过连接池可以避免频繁创建和销毁连接的开销,提高应用程序性能。
1 回复
Rust数据库连接池库deadpool-sqlite的使用:高效管理SQLite连接和异步操作
完整示例demo
下面是一个完整的示例,展示了如何使用deadpool-sqlite进行数据库操作:
use deadpool_sqlite::{Config, Pool, Runtime};
use rusqlite::params;
use tokio::task;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. 创建连接池配置
let config = Config::new("example.db")
.with_pool_size(5) // 设置最大连接数为5
.with_timeout(Some(10)); // 设置获取连接超时时间为10秒
// 2. 创建连接池
let pool = config.create_pool(Runtime::Tokio1)?;
// 3. 创建测试表
create_table(&pool).await?;
// 4. 插入数据
insert_user(&pool, "Alice").await?;
insert_user(&pool, "Bob").await?;
// 5. 查询数据
query_users(&pool).await?;
// 6. 更新数据
update_user(&pool, 1, "Alice Smith").await?;
// 7. 再次查询验证更新
query_users(&pool).await?;
Ok(())
}
async fn create_table(pool: &Pool) -> Result<(), Box<dyn std::error::Error>> {
let conn = pool.get().await?;
conn.execute(
"CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL
)",
[],
)?;
Ok(())
}
async fn insert_user(pool: &Pool, name: &str) -> Result<(), Box<dyn std::error::Error>> {
let conn = pool.get().await?;
let mut stmt = conn.prepare("INSERT INTO users (name) VALUES (?)")?;
stmt.execute(params![name])?;
println!("Inserted user: {}", name);
Ok(())
}
async fn query_users(pool: &Pool) -> Result<(), Box<dyn std::error::Error>> {
let conn = pool.get().await?;
let mut stmt = conn.prepare("SELECT id, name FROM users")?;
let rows = stmt.query_map([], |row| {
Ok((row.get::<_, i32>(0)?, row.get::<_, String>(1)?))
})?;
println!("Current users:");
for row in rows {
let (id, name) = row?;
println!(" {}: {}", id, name);
}
Ok(())
}
async fn update_user(
pool: &Pool,
user_id: i32,
new_name: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let conn = pool.get().await?;
let tx = conn.transaction()?;
tx.execute(
"UPDATE users SET name = ? WHERE id = ?",
params![new_name, user_id],
)?;
tx.commit()?;
println!("Updated user {} to {}", user_id, new_name);
Ok(())
}
async fn async_insert(pool: Pool) -> Result<(), Box<dyn std::error::Error>> {
task::spawn_blocking(move || {
let conn = pool.get()?;
let mut stmt = conn.prepare("INSERT INTO users (name) VALUES (?)")?;
stmt.execute(params!["Async User"])?;
Ok(())
})
.await??;
println!("Inserted user via async task");
Ok(())
}
这个完整示例演示了:
- 创建连接池并进行配置
- 创建数据库表
- 基本的CRUD操作
- 事务处理
- 异步操作
运行此程序前,请确保:
- 已添加正确的依赖到Cargo.toml
- 对数据库文件有读写权限
- 使用支持异步的Rust运行时(如tokio)