ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

sea-orm如何用连接池

sea-orm如何用连接池 Sea-ORM本身自带连接池你调用Database::connect(url).await返回的DatabaseConnection内部就是一个连接池不需要你自己再包一层Pool。1. 基础用法use sea_orm::{Database, DatabaseConnection, DbErr}; pub async fn get_db_conn() - ResultDatabaseConnection, DbErr { let url mysql://root:root127.0.0.1:3306/test; let db Database::connect(url).await?; Ok(db) }后续查询时let db get_db_conn().await?; let users t_sys_user::Entity::find() .all(db) .await?;每次查询时Sea-ORM 会自动从内部连接池中获取连接、执行 SQL、再归还连接。2. 自定义连接池参数如果你想配置最大连接数、超时、空闲时间等用ConnectOptionsuse sea_orm::{ConnectOptions, Database, DatabaseConnection, DbErr}; use std::time::Duration; pub async fn get_db_conn() - ResultDatabaseConnection, DbErr { let url mysql://root:root127.0.0.1:3306/test; let mut opt ConnectOptions::new(url); opt.max_connections(20) .min_connections(5) .connect_timeout(Duration::from_secs(5)) .acquire_timeout(Duration::from_secs(5)) .idle_timeout(Duration::from_secs(30)) .max_lifetime(Duration::from_secs(60 * 30)) .sqlx_logging(true); let db Database::connect(opt).await?; Ok(db) }常用参数参数作用max_connections连接池最大连接数min_connections连接池最小连接数connect_timeout建立连接超时acquire_timeout从连接池获取连接超时idle_timeout空闲连接关闭时间max_lifetime单个连接最大存活时间sqlx_logging是否打印 SQL 日志3. 全局共享连接池一般不要把DatabaseConnection每次都重新connect建议初始化一次然后全局共享。方式一OnceCelluse once_cell::sync::OnceCell; use sea_orm::{ConnectOptions, Database, DatabaseConnection, DbErr}; use std::time::Duration; static DB: OnceCellDatabaseConnection OnceCell::new(); pub async fn init_db() - Result(), DbErr { let url mysql://root:root127.0.0.1:3306/test; let mut opt ConnectOptions::new(url); opt.max_connections(20) .min_connections(5) .connect_timeout(Duration::from_secs(5)) .acquire_timeout(Duration::from_secs(5)); let db Database::connect(opt).await?; DB.set(db).map_err(|_| DbErr::Custom(数据库已初始化.into()))?; Ok(()) } pub fn get_db() - static DatabaseConnection { DB.get().expect(数据库未初始化请先调用 init_db()) }使用#[tokio::main] async fn main() { init_db().await.unwrap(); let db get_db(); let users t_sys_user::Entity::find() .all(db) .await .unwrap(); println!({users:?}); }方式二tokio::sync::OnceCell如果你希望延迟初始化并且第一次使用时才异步创建连接池use sea_orm::{ConnectOptions, Database, DatabaseConnection, DbErr}; use std::time::Duration; use tokio::sync::OnceCell; static DB: OnceCellDatabaseConnection OnceCell::const_new(); pub async fn get_db() - Resultstatic DatabaseConnection, DbErr { DB.get_or_try_init(|| async { let url mysql://root:root127.0.0.1:3306/test; let mut opt ConnectOptions::new(url); opt.max_connections(20) .min_connections(5) .connect_timeout(Duration::from_secs(5)) .acquire_timeout(Duration::from_secs(5)); Database::connect(opt).await }) .await }使用let db get_db().await?; let users t_sys_user::Entity::find() .all(db) .await?;4. 推荐写法如果你的项目是 Actix Web / Axum 这类异步服务推荐这样设计pub mod database { use sea_orm::{ConnectOptions, Database, DatabaseConnection, DbErr}; use std::time::Duration; use tokio::sync::OnceCell; static DB: OnceCellDatabaseConnection OnceCell::const_new(); pub async fn init_db() - Result(), DbErr { let url std::env::var(DATABASE_URL) .unwrap_or_else(|_| mysql://root:root127.0.0.1:3306/test.into()); let mut opt ConnectOptions::new(url); opt.max_connections(20) .min_connections(5) .connect_timeout(Duration::from_secs(5)) .acquire_timeout(Duration::from_secs(5)) .idle_timeout(Duration::from_secs(30)) .max_lifetime(Duration::from_secs(60 * 30)) .sqlx_logging(true); let db Database::connect(opt).await?; DB.set(db).map_err(|_| DbErr::Custom(数据库重复初始化.into()))?; Ok(()) } pub fn get_db() - static DatabaseConnection { DB.get().expect(数据库未初始化) } }启动时database::init_db().await.unwrap();业务代码里let db database::get_db(); let user t_sys_user::Entity::find() .one(db) .await?;关键点DatabaseConnection不是单个连接而是连接池。不要在每次请求里都Database::connect。推荐程序启动时初始化一次然后全局复用。如果需要自定义连接池大小、超时使用ConnectOptions。全局变量推荐用OnceCell或tokio::sync::OnceCell。需要我把连接池方案和之前的 AuSea-ORM本身自带连接池你调用Database::connect(url).await返回的DatabaseConnection内部就是一个连接池不需要你自己再包一层Pool。1. 基础用法use sea_orm::{Database, DatabaseConnection, DbErr}; pub async fn get_db_conn() - ResultDatabaseConnection, DbErr { let url mysql://root:root127.0.0.1:3306/test; let db Database::connect(url).await?; Ok(db) }后续查询时let db get_db_conn().await?; let users t_sys_user::Entity::find() .all(db) .await?;每次查询时Sea-ORM 会自动从内部连接池中获取连接、执行 SQL、再归还连接。2. 自定义连接池参数如果你想配置最大连接数、超时、空闲时间等用ConnectOptionsuse sea_orm::{ConnectOptions, Database, DatabaseConnection, DbErr}; use std::time::Duration; pub async fn get_db_conn() - ResultDatabaseConnection, DbErr { let url mysql://root:root127.0.0.1:3306/test; let mut opt ConnectOptions::new(url); opt.max_connections(20) .min_connections(5) .connect_timeout(Duration::from_secs(5)) .acquire_timeout(Duration::from_secs(5)) .idle_timeout(Duration::from_secs(30)) .max_lifetime(Duration::from_secs(60 * 30)) .sqlx_logging(true); let db Database::connect(opt).await?; Ok(db) }常用参数参数作用max_connections连接池最大连接数min_connections连接池最小连接数connect_timeout建立连接超时acquire_timeout从连接池获取连接超时idle_timeout空闲连接关闭时间max_lifetime单个连接最大存活时间sqlx_logging是否打印 SQL 日志3. 全局共享连接池一般不要把DatabaseConnection每次都重新connect建议初始化一次然后全局共享。方式一OnceCelluse once_cell::sync::OnceCell; use sea_orm::{ConnectOptions, Database, DatabaseConnection, DbErr}; use std::time::Duration; static DB: OnceCellDatabaseConnection OnceCell::new(); pub async fn init_db() - Result(), DbErr { let url mysql://root:root127.0.0.1:3306/test; let mut opt ConnectOptions::new(url); opt.max_connections(20) .min_connections(5) .connect_timeout(Duration::from_secs(5)) .acquire_timeout(Duration::from_secs(5)); let db Database::connect(opt).await?; DB.set(db).map_err(|_| DbErr::Custom(数据库已初始化.into()))?; Ok(()) } pub fn get_db() - static DatabaseConnection { DB.get().expect(数据库未初始化请先调用 init_db()) }使用#[tokio::main] async fn main() { init_db().await.unwrap(); let db get_db(); let users t_sys_user::Entity::find() .all(db) .await .unwrap(); println!({users:?}); }方式二tokio::sync::OnceCell如果你希望延迟初始化并且第一次使用时才异步创建连接池use sea_orm::{ConnectOptions, Database, DatabaseConnection, DbErr}; use std::time::Duration; use tokio::sync::OnceCell; static DB: OnceCellDatabaseConnection OnceCell::const_new(); pub async fn get_db() - Resultstatic DatabaseConnection, DbErr { DB.get_or_try_init(|| async { let url mysql://root:root127.0.0.1:3306/test; let mut opt ConnectOptions::new(url); opt.max_connections(20) .min_connections(5) .connect_timeout(Duration::from_secs(5)) .acquire_timeout(Duration::from_secs(5)); Database::connect(opt).await }) .await }使用let db get_db().await?; let users t_sys_user::Entity::find() .all(db) .await?;4. 推荐写法如果你的项目是 Actix Web / Axum 这类异步服务推荐这样设计pub mod database { use sea_orm::{ConnectOptions, Database, DatabaseConnection, DbErr}; use std::time::Duration; use tokio::sync::OnceCell; static DB: OnceCellDatabaseConnection OnceCell::const_new(); pub async fn init_db() - Result(), DbErr { let url std::env::var(DATABASE_URL) .unwrap_or_else(|_| mysql://root:root127.0.0.1:3306/test.into()); let mut opt ConnectOptions::new(url); opt.max_connections(20) .min_connections(5) .connect_timeout(Duration::from_secs(5)) .acquire_timeout(Duration::from_secs(5)) .idle_timeout(Duration::from_secs(30)) .max_lifetime(Duration::from_secs(60 * 30)) .sqlx_logging(true); let db Database::connect(opt).await?; DB.set(db).map_err(|_| DbErr::Custom(数据库重复初始化.into()))?; Ok(()) } pub fn get_db() - static DatabaseConnection { DB.get().expect(数据库未初始化) } }启动时database::init_db().await.unwrap();业务代码里let db database::get_db(); let user t_sys_user::Entity::find() .one(db) .await?;关键点DatabaseConnection不是单个连接而是连接池。不要在每次请求里都Database::connect。推荐程序启动时初始化一次然后全局复用。如果需要自定义连接池大小、超时使用ConnectOptions。全局变量推荐用OnceCell或tokio::sync::OnceCell。需要我把连接池方案和之前的 Auth Middleware 整合成一份完整的 Cargo.toml 依赖清单吗th Middleware 整合成一份完整的 Cargo.toml 依赖清单吗
返回列表