问题在于每个get方法(例如上面)都调用establish_pooled_connection(),这样就会重新实例化一切...
我也曾经遇到过设置池连接的问题,所以我想留下我所做的事情。
我成功地在rocket/diesel应用程序中使用了池连接,通过将已建立的池添加到服务器状态并从各个函数通过该服务器状态访问数据库来实现。
use diesel::{
r2d2::{ConnectionManager, Pool, PooledConnection},
MysqlConnection,
};
pub type DbPool = Pool<ConnectionManager<MysqlConnection>>;
pub struct ServerState {
pub db_pool: DbPool
}
Rocket允许我们在使用
build()
构建服务器时,通过
.manage()
调用来定义服务器状态。
#[rocket::main]
pub async fn main() {
let db_pool: DbPool = establish_connection_pool();
rocket::build()
.mount("/", routes![test])
.manage(ServerState { db_pool })
.launch()
.await
.expect("Failed to launch rocket server.")
}
因为Rocket允许我们从函数中检索服务器状态,只要它们具有Rocket的宏(
get
,
post
等),因此我们可以从服务器状态中检索数据库。
use rocket::{get, serde::json::Json, State};
#[get("/test?<user_id>")]
pub async fn test(
state: &State<ServerState>,
user_id: String
) -> Result<Json<User>, Error> {
let pooled = &state.db_pool.get()?;
pooled.transaction(|| {
})
}
我在处理此事时所用的版本如下。
diesel = { version = "1.4.8", features = ["r2d2", "mysql", "chrono"] }
rocket = { version = "0.5.0-rc.1", features = ["json"] }
需要考虑的其他事项
有些人希望像我上面所做的那样直接使用r2d2
建立连接池。我个人认为,将连接池作为服务器状态中的字段传递,可以更好地控制编写集成测试。但是,还有其他处理连接池的方法值得您了解。
Rocket
提供了自己的解决方案来处理池化数据库连接,分别是rocket_sync_db_pools
[1]和rocket_db_pools
[2]。如果您使用ORM(如diesel
[3]和sqlx
[4])与库中涵盖的数据库一起使用,则强烈建议您研究它们。
只需在项目的根目录中设置一个Rocket.toml
文件即可。
[global.databases]
test_db = { url = "mysql://mysql:password@localhost:5432/test_db_name" }
现在,通过发挥 database
宏的威力,您可以轻松建立连接。
#[macro_use]
extern crate rocket_sync_db_pools;
#[database("test_db")]
pub struct TestDbConn(diesel::MysqlConnection);
#[get("/test?<user_id>")]
pub async fn test(
conn: TestDbConn,
user_id: String
) -> Result<Json<User>, Error> {
conn.run(move || {
})
}
[1] 对于像diesel
这样的同步ORM,请使用rocket_sync_db_pools
。
https://api.rocket.rs/v0.5-rc/rocket_sync_db_pools/index.html#
[2] 对于像deadpool-postgres
和sqlx
这样的异步ORM,请使用rocket_db_pools
。https://api.rocket.rs/v0.5-rc/rocket_db_pools/index.html#
[3] https://api.rocket.rs/v0.5-rc/rocket_sync_db_pools/index.html#database-support
[4] https://api.rocket.rs/v0.5-rc/rocket_db_pools/index.html#supported-drivers