rust连接postgresql数据库
·
1、同步操作
引入crate:
postgres = "0.19.7"
use postgres::{Client, NoTls, error::Error};
fn main() -> Result<(), Error> {
let mut client = Client::connect("host=localhost port=5432 dbname=xxxxxdb user=postgres password=123456", NoTls).unwrap();
for row in client.query("select id,name,file_name,create_time::TEXT,valid from xxxxx", &[])?{
let id: i32 = row.get("id");
let name: &str = row.get("name");
let file_name: &str = row.get("file_name");
let create_time: &str = row.get(3);
let valid: bool = row.get(4);
println!("id:{}, name:{}, file_name:{},create_time:{:?} valid:{}", id, name, file_name,create_time, valid);
}
let rows = client.query("select count(*)::integer as a from xxxxx where id=$1", &[&1])?;
let cnt: i32 = rows[0].get("a");
println!("cnt={}", cnt);
Ok(())
}
注意:用户名不要使用root。否则报错:
thread 'main' panicked at src\main.rs:5:115:
called `Result::unwrap()` on an `Err` value: Error { kind: Parse, cause: Some(Custom { kind: InvalidInput, error: Utf8Error { valid_up_to: 0, error_len: Some(1) } }) }
注意:select count(*) ::integer as a from xxxx的写法,做postgres内的类型转换,否则count(*)默认作为i8返回,rust获取数据时报错。
2、异步操作
引入Crate:
tokio = {version = "1.35.1", features = ["full"]}
tokio-postgres = "0.7.10"
chrono = "0.4.34"
use tokio_postgres::{NoTls, Error};
use chrono::prelude::{DateTime, Utc};
use std::time::SystemTime;
#[tokio::main]
async fn main() -> Result<(), Error> {
println!("测试tokio异步版本postgres操作");
let (client, connection) = tokio_postgres::connect("host=localhost port=5432 dbname=xxxxxdb user=postgres password=123456", NoTls).await.unwrap();
//启动线程监控数据库连接是否正常
tokio::spawn(async move {
if let Err(e) = connection.await{
eprintln!("connection error:{}", e);
}
});
let rows = client.query("select id,name,file_name,create_time,valid from xxxxx", &[]).await?;
for row in rows{
let id: i32 = row.get("id");
let name: &str = row.get("name");
let file_name: String = row.get("file_name");
let create_time: SystemTime = row.get("create_time");
let dt: DateTime<Utc> = create_time.clone().into();
println!("id={}, name={}, file_name={}, create_time={}", id, name, file_name, dt.format("%Y-%M-%d %H:%m:%S"));
}
let rows = client.query("select max(id)::integer from xxxxx", &[]).await?;
let max_id:i32 = rows[0].get(0);
println!("max id={}", max_id);
let new_id = max_id + 1;
let new_name: String = format!("xxxxx-{}", new_id);
let new_file_name: String = format!("xxxxx_file_name-{}", new_id);
let modify_row_cnt = client.execute("insert into xxxxx(id,name,file_name,create_time,valid) values($1,$2,$3,$4,$5)", &[&new_id, &new_name, &new_file_name, &SystemTime::now(), &true]).await?;
println!("affect row count:{}", modify_row_cnt);
let affect_row_count = client.execute("update xxxxx set file_name='xxxxx_file_name-' || id::TEXT where file_name=''", &[]).await?;
println!("affect row count:{}", affect_row_count);
let affect_row_count = client.execute("delete from xxxxx where id=$1", &[&new_id]).await?;
println!("delete row count:{}", affect_row_count);
let trans = client.transaction().await?;
trans.execute("update xxxxx set valid=$1,remark=name || id::TEXT where id=$2", &[&false, &1]).await?;
trans.execute("update xxxxx set valid=$1,remark=name || id::TEXT where id=$2", &[&true, &2]).await?;
trans.commit().await?;
Ok(())
}
注意:postgresql中的timestamp类型可以直接转换为rust中的SystemTime;要转换为我们熟悉的年月日时分秒格式,还需要借助chrono crate。
代码中含增、删、改、查、事务范例。
3、异步+连接池
引入crate:
tokio = {version = "1.35.1", features = ["full"]}
tokio-postgres = "0.7.10"
deadpool-postgres = {version = "0.9.0"}
chrono = "0.4.34"
//pool
//let url = "host=localhost port=5432 dbname=sprucedb user=postgres password=123456".to_string();
let mut pg_config = tokio_postgres::Config::new();
pg_config.host("localhost");
pg_config.port(5432);
pg_config.dbname("xxxxxdb");
pg_config.user("postgres");
pg_config.password("123456");
let mgr_config = ManagerConfig{
recycling_method: RecyclingMethod::Fast
};
let mgr = Manager::from_config(pg_config, NoTls, mgr_config);
let pool = Pool::new(mgr, 16);
let client = pool.get().await.unwrap();
let rows = tokio::spawn(async move{
client.query("select id,name,file_name,create_time,valid from xxxxx", &[])
.await
.expect("query failed")
})
.await
.expect("task failed");
for row in rows{
let id: i32 = row.get("id");
let name: String = row.get("name");
println!("connect pool demo output:{}, {}", id, name);
}
let client2 = pool.get().await.unwrap();
let rows2 = client2.query("select 20+5::integer", &[]).await.unwrap();
let sum:i32 = rows2[0].get(0);
println!("20+5={}", sum);
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)