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
运行即可。
来源:https://www.cnblogs.com/b612/p/12026805.html