Actix-web Rust連接Postgres數據庫


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作為數據庫連接。直接支持異步省去很多麻煩。

初始化項目

直接用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運行即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM