Sea-ORM本身自带连接池,你调用:
Database::connect(url).await返回的DatabaseConnection内部就是一个连接池,不需要你自己再包一层Pool。
1. 基础用法
use sea_orm::{Database, DatabaseConnection, DbErr}; pub async fn get_db_conn() -> Result<DatabaseConnection, DbErr> { let url = "mysql://root:root@127.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. 自定义连接池参数
如果你想配置最大连接数、超时、空闲时间等,用ConnectOptions:
use sea_orm::{ConnectOptions, Database, DatabaseConnection, DbErr}; use std::time::Duration; pub async fn get_db_conn() -> Result<DatabaseConnection, DbErr> { let url = "mysql://root:root@127.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,建议初始化一次,然后全局共享。
方式一:OnceCell
use once_cell::sync::OnceCell; use sea_orm::{ConnectOptions, Database, DatabaseConnection, DbErr}; use std::time::Duration; static DB: OnceCell<DatabaseConnection> = OnceCell::new(); pub async fn init_db() -> Result<(), DbErr> { let url = "mysql://root:root@127.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: OnceCell<DatabaseConnection> = OnceCell::const_new(); pub async fn get_db() -> Result<&'static DatabaseConnection, DbErr> { DB.get_or_try_init(|| async { let url = "mysql://root:root@127.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: OnceCell<DatabaseConnection> = OnceCell::const_new(); pub async fn init_db() -> Result<(), DbErr> { let url = std::env::var("DATABASE_URL") .unwrap_or_else(|_| "mysql://root:root@127.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。
需要我把连接池方案和之前的 Au
Sea-ORM本身自带连接池,你调用:
Database::connect(url).await返回的DatabaseConnection内部就是一个连接池,不需要你自己再包一层Pool。
1. 基础用法
use sea_orm::{Database, DatabaseConnection, DbErr}; pub async fn get_db_conn() -> Result<DatabaseConnection, DbErr> { let url = "mysql://root:root@127.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. 自定义连接池参数
如果你想配置最大连接数、超时、空闲时间等,用ConnectOptions:
use sea_orm::{ConnectOptions, Database, DatabaseConnection, DbErr}; use std::time::Duration; pub async fn get_db_conn() -> Result<DatabaseConnection, DbErr> { let url = "mysql://root:root@127.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,建议初始化一次,然后全局共享。
方式一:OnceCell
use once_cell::sync::OnceCell; use sea_orm::{ConnectOptions, Database, DatabaseConnection, DbErr}; use std::time::Duration; static DB: OnceCell<DatabaseConnection> = OnceCell::new(); pub async fn init_db() -> Result<(), DbErr> { let url = "mysql://root:root@127.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: OnceCell<DatabaseConnection> = OnceCell::const_new(); pub async fn get_db() -> Result<&'static DatabaseConnection, DbErr> { DB.get_or_try_init(|| async { let url = "mysql://root:root@127.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: OnceCell<DatabaseConnection> = OnceCell::const_new(); pub async fn init_db() -> Result<(), DbErr> { let url = std::env::var("DATABASE_URL") .unwrap_or_else(|_| "mysql://root:root@127.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 依赖清单吗?