八、Rust 集成 Sqlx Rust 语言级异步,是 xxx 版添加进来的特性。如果只是需要一款支持异步的连接池工具,推荐 tokio-postgres、deadpool-postgres。而用于生产工序,还是需要 ORM 的加入。本节我们来学习一下 sqlx。 本节需要 PostgreSQL 数据库,需要读者提前准备,并假定实例中已包含名为 postgres 的库,且账号为:postgres:postgres。
1、目录结构
.
├── Cargo
.lock
├── Cargo
.toml
├── README
.md
├── config
.yaml
└── src
├── boot
│ ├── db
.rs
│ └── mod
.rs
├── main
.rs
└── module
├── mod
.rs
└── user
├── api
.rs
├── mod
.rs
└── model
.rs
2、开始集成
1)追加依赖:Cargo.toml
serde_yaml
= "0.8.13"
sqlx
= {version
= "0.4.0-beta.1", default-features
= false, features
= ["runtime-tokio", "postgres", "macros", "chrono"]}
once_cell
= "1.3.1"
chrono
= { version
= "0.4.15",features
= ["serde"] }
2)配置文件:config.yaml
server:
port: 8080
log: data/logs/app/web.log
env: dev
postgres:
dsn: postgres
://postgres
:postgres@192.168.24.251
:5432/postgres
min: 5
max: 15
3)代码:src/boot/mod.rs
use std
::sync
::Arc
;
use once_cell
::sync
::OnceCell
;
use serde
::Deserialize
;
use crate
::boot
;
pub mod db
;
#
[derive(Debug
, Deserialize
)]
pub
struct Conf
{
pub server
: Server
,
pub postgres
: Option
<Postgres
>,
}
#
[derive(Debug
, Deserialize
)]
pub
struct Server
{
pub port
: u32
,
pub log
: String
,
pub env
: String
,
}
#
[derive(Debug
, Deserialize
)]
pub
struct Postgres
{
pub dsn
: String
,
pub min
: u32
,
pub max
: u32
,
}
#
[allow(dead_code
)]
pub fn
global() -> &'
static Arc
<Conf
> {
static CONFIG
: OnceCell
<Arc
<Conf
>> = OnceCell
::new();
CONFIG
.get_or_init(|| {
let s
= std
::fs
::read_to_string(&"config.yaml").unwrap();
Arc
::new(serde_yaml
::from_str(&s
).unwrap())
})
}
pub fn
start() {
boot
::db
::init_db_pool()
}
impl Conf
{
#
[allow(dead_code
)]
pub fn
get_env(&self
) -> String
{
self
.server
.env
.clone()
}
#
[allow(dead_code
)]
pub fn
addr(&self
) -> String
{
format
!("0.0.0.0:{}", self
.server
.port
)
}
}
4)代码:src/boot/db.rs
use once_cell
::sync
::OnceCell
;
use sqlx
::{Pool
, Postgres
};
use sqlx
::postgres
::PgPoolOptions
;
pub
static POSTGRES_POOL
: OnceCell
<Pool
<Postgres
>> = OnceCell
::new();
pub fn
init_db_pool() {
if let
Some(pg
) = &crate
::boot
::global().postgres
{
let pool
= PgPoolOptions
::new()
.min_connections(pg
.min
)
.max_connections(pg
.max
)
.connect_lazy(&pg
.dsn
).unwrap();
assert
!(POSTGRES_POOL
.set(pool
).is_ok());
println
!("datasource: {}\n min: {}\n max: {}", pg
.dsn
, pg
.min
, pg
.max
)
}
}
#
[allow(dead_code
)]
pub fn
get_pool() -> Option
<&'
static Pool
<Postgres
>> {
POSTGRES_POOL
.get()
}
5)代码:src/main.rs
#
[macro_use
]
extern crate validator_derive
;
use actix_web
::{App
, HttpServer
};
mod boot
;
mod module
;
#
[actix_web
::main
]
async fn
main() -> std
::io
::Result
<()> {
boot
::start();
HttpServer
::new(move
|| App
::new()
.service(module
::handler
::api_routes())
).bind(boot
::global().addr())?.run().await
}
至此,便使我们的项目集成了 Sqlx,这款 Rust 异步 ORM 框架。现在,可以尝试编译,和启动我们的服务。
$ cargo run
Compiling rust-demo v0.1.0
(~/Rust-Study/rust-demo
)
Finished dev
[unoptimized + debuginfo
] target
(s
) in 6.52s
Running
`target/debug/rust-demo`
datasource: postgres://postgres:postgres@192.168.24.251:5432/postgres
min: 5
max: 15
或
$ ./target/debug/rust-demo
datasource: postgres://postgres:postgres@192.168.24.251:5432/postgres
min: 5
max: 15
为使每一小节,都尽可能简单/轻巧,本节就先这样。下一节,我们具体来看,使用 Sqlx 访问数据库 !~