【rust】8、连接数据库:sqlx

sqlx 是 rust 的数据库访问工具, 本身并不是 orm,但常见的 orm 都是基于它实现的。其有如下特点:

  • 支持异步,适合高并发
  • 编译时检查:cargo build 时检查执行 sql,校验响应值
  • 支持多数据库:mysql、pg、sqlite 等
  • 支持主流 rust 运行时:tokio、async-std、actix、native-tls、rustls等
  • 内置连接池

一、数据库、依赖、环境变量

本文操作 pg,首先建表

DROP TABLE IF EXISTS course;
CREATE TABLE course (id INT8 NOT NULL,teacher_id INT4 NOT NULL,name VARCHAR(255) NOT NULL,time DATE DEFAULT NOW()
);
INSERT INTO course VALUES (1, 11, 'cml', '2022-03-25');
INSERT INTO course VALUES (2, 22, 'cc', '2022-03-25');
INSERT INTO course VALUES (3, 33, 'mm', '2022-03-25');
ALTER TABLE course ADD CONSTRAINT course_pkey PRIMARY KEY (id);

用 cargo new 新建项目,添加依赖:

cargo add sqlx -F postgres -F runtime-tokio-rustls -F macros -F chrono
cargo add dotenv # 环境变量工具。本例中将使用此工具处理数据库连接字符串。
cargo add chrono -F serde # 时间工具
cargo add serde -F derive # 序列化
cargo add actix-web # actix 运行时
cargo add actix-rt # actix 运行时

环境变量

数据库地址可以放在配置文件里,例如在根目录新建一个 .env 文件,内容如下:

DATABASE_URL=postgres://cml:123456@192.168.1.239:5432/postgres

二、增删改查

2.1 完整示例

  • dotenv().ok():在访问环境变量之前检查一下,防止因读取环境变量失败导致程序 panic。
  • env::var(“DATABASE_URL”):读取环境变量文件中的数据库连接字符串
  • PgPoolOptions::new().connect():实例化一个数据库连接池
  • sqlx::query!(“sql”) .fetch_all(&pool):执行sql语句

工程目录结构:

│  .env
│  Cargo.toml 
├─src
│      main.rs

示例代码:

use chrono::NaiveDate;
use dotenv::dotenv;
use sqlx::postgres::PgPoolOptions;
use std::env;#[derive(Debug)]
pub struct Course {pub id: i64,pub teacher_id: i32,pub name: String,pub time: Option<NaiveDate>,
}#[actix_rt::main]
async fn main() -> Result<(), sqlx::Error> {println!("Hello, world!");dotenv().ok();读取所有的环境变量// for (key, value) in env::vars() {//     println!("环境变量内容:{}: {}", key, value);// }let connection_str = env::var("DATABASE_URL").expect("数据库连接字符串获取失败,请检查env文件是否已配置数据库连接字符串");println!("数据库连接字符串是:{}", connection_str);let pool = PgPoolOptions::new().max_connections(5).connect(&connection_str).await?;println!("db_pool is : {:?}", pool);//查询所有let list = sqlx::query!("select * from course").fetch_all(&pool).await?;let mut vec = vec![];for row in list {vec.push(Course {id: row.id,teacher_id: row.teacher_id,name: row.name,time: row.time,})}println!("数据库中的所有数据:{:#?}", vec);//查询单个let list2 = sqlx::query!(r#"select * from course where id = $1"#, 1).fetch_all(&pool).await?;let mut vec2 = vec![];for row in list2 {vec2.push(Course {id: row.id,teacher_id: row.teacher_id,name: row.name,time: row.time,})}println!("查询单个{:#?}", vec2);// 增加let insert = sqlx::query!(r#"INSERT INTO course VALUES ($1, $2, $3)"#,100000,11,"gg").fetch_all(&pool).await?;// 更新let update = sqlx::query!(r#"update course set name=$1"#, "ogg").fetch_all(&pool).await?;Ok(())
}// cargo r
Hello, world!
数据库连接字符串是:postgres://postgres:pass@ip:5432/postgres
db_pool is : Pool { size: 1, num_idle: 1, is_closed: false, options: PoolOptions { max_connections: 5, min_connections: 0, connect_timeout: 30s, max_lifetime: Some(1800s), idle_timeout: Some(600s), test_before_acquire: true } }
数据库中的所有数据:[Course {id: 1,teacher_id: 11,name: "cml",time: Some(2022-03-25,),},Course {id: 2,teacher_id: 22,name: "cc",time: Some(2022-03-25,),},Course {id: 3,teacher_id: 33,name: "mm",time: Some(2022-03-25,),},
]
查询单个[Course {id: 1,teacher_id: 11,name: "cml",time: Some(2022-03-25,),},
]// 执行完时,查询数据库如下:
postgres=# select * from course;id   | teacher_id | name |    time
--------+------------+------+------------1 |         11 | ogg  | 2022-03-252 |         22 | ogg  | 2022-03-253 |         33 | ogg  | 2022-03-25100000 |         11 | ogg  | 2024-02-21
(4 rows)

参考:https://www.cnblogs.com/Naylor/p/16062584.html

2.2 query

let sql = format!(r#"DROP TABLE IF EXISTS {}"#, tmp_table_name);
let r = sqlx::query(&sql).execute(&pool).await?;
println!("sql: {} r: {:?}", sql, r);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/485159.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

贷齐乐系统最新版SQL注入(无需登录绕过WAF可union select跨表查询)

一、环境 已上传资源&#xff08;daiqile&#xff09; 二、代码解释 1.1Request 不管get请求还是post请求都可以接收到 1.2过滤的还挺多 1.3第二个WAF把数据分为两个了一个Key一个value&#xff0c;全是explode的功劳 1.4submit是if进入的前提 很明显走进来了 1.5那我们在这…

31.云原生Istio可观测性之官网Bookinfo应用实战演示

云原生专栏大纲 文章目录 可观测性kiali介绍Overview&#xff08;概观&#xff09;Application&#xff08;应用维度&#xff09;workloads&#xff08;负载维度&#xff09;Services&#xff08;服务维度&#xff09;Istio Config&#xff08;配置维度&#xff09; Kiali部署…

后台的日志存储

日志乱象 日志是日常开发中最有可能被忽视&#xff0c;最容易被滥用的一个模块。被忽视是因为打日志实在是一个再简单不过的事&#xff0c;前人设计好了一个logback.xml&#xff0c;后面只需要依样画葫芦定义一个logger&#xff0c;随手一个info调用就搞定 &#xff0c;他甚至…

【Linux】普通用户sudo失败怎么办

普通用户&#xff0c;sudo失败报错怎么办 问题分析如何解决成功 问题分析 新建的普通用户sudo失败 sudo提权&#xff0c;是以root的身份执行命令。 当我们用sudo提升权限的时候&#xff0c;这里有个问题&#xff0c;Linux会提示我们输入当前普通用户的密码——这就有点不好。…

【FreeRTOS基础入门】软件定时器

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、软件定时器的介绍1.1 软件定时器的特性1.2 软件定时器的特性1.3 守护任务 二、软件定时器的使用2.1 回调函数2.2 创建定时器创建动态定时器创建静态定时器 …

R语言实现分位数回归和二次分位数回归

大家好&#xff0c;我是带我去滑雪&#xff01;新的一年&#xff0c;新的气象&#xff0c;在接下来的日子里我将继续和各位小伙伴们分享我在科研道路上&#xff0c;学习的一些知识&#xff01; 分位数回归和二次分位数回归是统计学中用于分析因变量与自变量之间关系的方法&…

Android14 InputManager-InputManagerService环境的构造

IMS分为Java层与Native层两个部分&#xff0c;其启动过程是从Java部分的初始化开始&#xff0c;进而完成Native部分的初始化。 □创建新的IMS对象。 □调用IMS对象的start&#xff08;&#xff09;函数完成启动 同其他系统服务一样&#xff0c;IMS在SystemServer中的ServerT…

c++ template-1

第一章 函数模版 1.1 初识模版 1.1.1定义模版 以下就是一个函数模板&#xff0c;它返回两个数之中的最大值&#xff1a; template<typename T> T max (T a, T b) { // 如果 b < a, 返回 a&#xff0c;否则返回 b return b < a ? a : b; } 模板参数是 typename T…

采用SSI技术的FPGA器件

9个关于SSI芯片的必知问题-腾讯云开发者社区-腾讯云 (tencent.com)https://cloud.tencent.com/developer/article/1530543

Docker硬件直通:如何在容器中高效利用GPU与硬盘资源

Docker硬件直通&#xff1a;如何在容器中高效利用GPU与硬盘资源 引言Docker基础容器与虚拟机的区别Docker的工作原理 访问服务器硬件资源概述为何需要在Docker容器中访问硬件资源可访问的硬件资源类型 在Docker中使用GPU配置Docker以使用宿主机的GPU资源安装NVIDIA Docker插件 …

【操作系统】磁盘存储空间的管理

实验5 磁盘存储空间的管理 一、实验目的 磁盘是用户存放程序和数据的存储设备&#xff0c;磁盘管理的主要目的是充分有效地利用磁盘空间。本实验模拟实现磁盘空间的分配与回收&#xff0c;使学生对磁盘空间的管理有一个较深入的理解。 二、实验内容 实验任务&#xff1a;用位…

企业计算机服务器中了crypt勒索病毒怎么办,crypt勒索病毒解密数据恢复

计算机服务器设备为企业的生产运营提供了极大便利&#xff0c;企业的重要核心数据大多都存储在计算机服务器中&#xff0c;保护企业计算机服务器免遭勒索病毒攻击&#xff0c;是一项艰巨的工作任务。但即便很多企业都做好的了安全运维工作&#xff0c;依旧免不了被勒索病毒攻击…