Actix-web Rust連接Postgres數據庫
Rust1.39
支持了異步async
,await
,Actix-web在2.0.0-alpha
支持了原生異步寫法,所以本文中使用的Actix-web版本為2.0.0-alpha.4
。
Actix-web官方例子使用的是r2d2連接池庫,這個庫並不是異步庫,需要用web::block
的api,不是很方便,我找到了一個deadpool-postgres
連接池庫,采用tokio-postgres
作為數據庫連接。直接支持異步省去很多麻煩。
- deadpool-postgres
- tokio-postgres
- actix-web v:
2.0.0-alpha.4
初始化項目
直接用cargo new pgtest
來初始化一個項目
修改Cargo.toml
[package]
name = "pgtest"
version = "0.1.0"
authors = ["yuxq"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
actix-web = "2.0.0-alpha.4"
# actix運行時
actix-rt = "1.0.0-alpha.3"
tokio-postgres = "0.5.0-alpha.2"
deadpool-postgres = "0.2.3"
修改默認main方法
官方運行異步actix服務器是使用actix-rt庫,方法如下
#[actix_rt::main]
async fn main()-> std::io::Result<()> {
HttpServer::new( ||
App::new()
.bind("127.0.0.1:8080")?
.start()
.await
}
創建postgres連接池
use deadpool_postgres::{Manager, Pool};
use tokio_postgres::{Config, NoTls};
#[actix_rt::main]
async fn main()-> std::io::Result<()> {
let mut cfg = Config::new();
cfg.host("localhost");//數據庫地址
cfg.user("db");//數據庫用戶名
cfg.password("db");//數據庫密碼
cfg.dbname("asynctest");//數據庫名稱
let mgr = Manager::new(cfg, tokio_postgres::NoTls);
let pool = Pool::new(mgr, 15);//最大15個連接
}
綁定連接池對象
actix-web官方文檔對State
的解釋
Application state is shared with all routes and resources within the same scope. State can be accessed with the
web::Data
extractor. State is also available for route matching guards and middlewares.
我們可以把對象綁定進Application,同所有具有相同命名空間的路徑和資源共享,之后再用web::Data
提取器獲取到。
use deadpool_postgres::{Manager, Pool};
use tokio_postgres::{Config, NoTls};
#[actix_rt::main]
async fn main()-> std::io::Result<()> {
let mut cfg = Config::new();
cfg.host("localhost");//數據庫地址
cfg.user("db");//數據庫用戶名
cfg.password("db");//數據庫密碼
cfg.dbname("asynctest");//數據庫名稱
let mgr = Manager::new(cfg, tokio_postgres::NoTls);
let pool = Pool::new(mgr, 15);//最大15個連接
HttpServer::new( move ||
App::new().data(pool.clone())
.bind("127.0.0.1:8080")?
.start()
.await
}
在handler
中獲取數據庫連接池
首先讓我們創建一個具有web::Data
提取器的handler
我在本機上跑了一個docker
運行postgres
數據庫
創建了一個users
的表,字段有【id,name,age】例子只獲取name
use actix_web::{web,Responder};
use deadpool_postgres::{Manager, Pool};
async fn get_user(db:web::Data<Pool>)->impl Responder{
let mut conn=db.get().await.unwrap();
let rows=conn.query("select * from users",&[]).await.unwrap();
let v:String=rows[0].get("name");//get參數可以是str,也可以是i32,獲取第幾個。但是必須要指明獲取的類型
format!("{}",v)
}
將handler綁定至server application
HttpServer::new( move ||
App::new().data(pool.clone()).route("user",web::get().to(get_user))
.bind("127.0.0.1:8080")?
.start()
.await
通過cargo run
運行即可。