简介

sqlx 是 rust 中的一个数据库访问工具。具有以下特点:

  • 异步:原生就支持异步,在并发性高的场合能够得到更好的支持
  • 编译时检查查询:sqlx可以在 cargo build 的时候检查执行sql和响应值
  • 多数据库支持:PostgresSQL,MySql,SqlLite,MSSql,MariaDB
  • 多运行时支持:支持主流 rust 运行时。async-std,tokio,actix,native-tls,rustls
  • 内置连接池,支持查询缓存

不足

sqlx 不是 orm 框架

实践

本例将使用 sqlx 访问 postgressql 数据库,实现简单的增删改查功能

数据库

数据库采用 postgreSQL,初始建表语句如下:


-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS "public"."course";
CREATE TABLE "public"."course" (
  "id" int8 NOT NULL,
  "teacher_id" int4 NOT NULL,
  "name" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
  "time" date DEFAULT now()
)
;
-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO "public"."course" VALUES (1, 11, 'cml', '2022-03-25');
INSERT INTO "public"."course" VALUES (2, 22, 'cc', '2022-03-25');
INSERT INTO "public"."course" VALUES (3, 33, 'mm', '2022-03-25');
-- ----------------------------
-- Primary Key structure for table course
-- ----------------------------
ALTER TABLE "public"."course" ADD CONSTRAINT "course_pkey" PRIMARY KEY ("id");

依赖

使用 cargo new 一个新的 project ,并在 toml 中添加如下依赖:

  • sqlx:数据库访问工具
  • dotenv:环境变量工具。本例中将使用此工具处理数据库连接字符串。此工具除了会加载文件中的配置信息,还会加载windows操作系统中的环境变量信息,如 JAVA_HOME 等。
  • chrono:时间和日期工具
  • serde:序列化和反序列化工具
  • actix-web&actix-rt:actix 运行时
[dependencies]
actix-rt="2.6.0"
actix-web="3.3.3"
serde={version="1.0.134",features=["derive"]}
chrono={version="0.4.19",features=["serde"]}
dotenv="0.15.0"
sqlx={version="0.5.10",features=["postgres","runtime-tokio-rustls","macros","chrono"]}

环境变量

一般来说,数据库连接字符串都不会硬编码到程序代码中,需要有一个类似配置文件的文件,将连接信息放文件中, 运行时从文件加载数据库连接信息。

根目录新建一个 .env 的文件,并在里面配置数据库连接字符串:

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

其中, rust_sqlx 为数据库实例的名称

CRUD

说明

在 main 中编写简单的 crud 示例。

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

工程目录结构

│  .env
│ Cargo.toml
│ course.sql
│ README.md
│ tree.txt

├─src
│ main.rs

示例代码


use actix_web::{web, App, HttpServer};
use chrono::NaiveDate;
use dotenv::dotenv;
use sqlx::postgres::PgPoolOptions;
use std::env;
#[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("postgres://cml:123456@192.168.1.239:5432/rust_sqlx")
        .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(())
}
#[derive(Debug)]
pub struct Course {
    pub id: i64,
    pub teacher_id: i32,
    pub name: String,
    pub time: Option<NaiveDate>,
}

以上代码输出

Hello, world!
数据库连接字符串是:postgres://cml:123456@192.168.1.239:5432/rust_sqlx
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: "ogg",
time: Some(
2022-03-25,
),
},
Course {
id: 2,
teacher_id: 22,
name: "ogg",
time: Some(
2022-03-25,
),
},
Course {
id: 3,
teacher_id: 33,
name: "ogg",
time: Some(
2022-03-25,
),
},
Course {
id: 100000,
teacher_id: 11,
name: "ogg",
time: Some(
2022-03-26,
),
},
]
查询单个[
Course {
id: 1,
teacher_id: 11,
name: "ogg",
time: Some(
2022-03-25,
),
},
]

代码

https://gitee.com/naylor_personal/rust-actix/tree/master/workspace/db

引用

Rust-Sqlx极简教程的更多相关文章

  1. Typora极简教程

    Typora极简教程 ” Markdown 是一种轻量级标记语言,创始人是约翰·格鲁伯(John Gruber).它允许人们 “使用易读易写的纯文本格式编写文档,然后转换成有效的 HTML 文档.” ...

  2. CentOS安装使用.netcore极简教程(免费提供学习服务器)

    本文目标是指引从未使用过Linux的.Neter,如何在CentOS7上安装.Net Core环境,以及部署.Net Core应用. 仅针对CentOS,其它Linux系统类似,命令环节稍加调整: 需 ...

  3. Asky极简教程:零基础1小时学编程,已更新前8节

    Asky极简架构 开源Asky极简架构.超轻量级.高并发.水平扩展.微服务架构 <Asky极简教程:零基础1小时学编程>开源教程 零基础入门,从零开始全程演示,如何开发一个大型互联网系统, ...

  4. Python 极简教程(八)字符串 str

    由于字符串过于重要,请认真看完并保证所有代码都至少敲过一遍. 对于字符串,前面在数据类型中已经提到过.但是由于字符串类型太过于常用,Python 中提供了非常多的关于字符串的操作.而我们在实际编码过程 ...

  5. Nginx 极简教程(快速入门)

    作者:dunwu github.com/dunwu/nginx-tutorial 推荐阅读(点击即可跳转阅读) 1. SpringBoot内容聚合 2. 面试题内容聚合 3. 设计模式内容聚合 4.  ...

  6. 【转】Typora极简教程

    Typora极简教程 Typora download ” Markdown 是一种轻量级标记语言,创始人是约翰·格鲁伯(John Gruber).它允许人们 “使用易读易写的纯文本格式编写文档,然后转 ...

  7. nginx极简教程

    Nginx 极简教程 本项目是一个 Nginx 极简教程,目的在于帮助新手快速入门 Nginx. examples 目录中的示例模拟了工作中的一些常用实战场景,并且都可以通过脚本一键式启动,让您可以快 ...

  8. NodeJS 极简教程 <1> NodeJS 特点 & 使用场景

    NodeJS 极简教程 <1> NodeJS 特点 & 使用场景 田浩 因为看开了所以才去较劲儿.   1. NodeJS是什么 1.1 Node.js is a JavaScri ...

  9. 自制 os 极简教程1:写一个操作系统有多难

    为什么叫极简教程呢?听我慢慢说 不知道正在阅读本文的你,是否是因为想自己动手写一个操作系统.我觉得可能每个程序员都有个操作系统梦,或许是想亲自动手写出来一个,或许是想彻底吃透操作系统的知识.不论是为了 ...

  10. python极简教程04:进程和线程

    测试奇谭,BUG不见. 大家好,我是谭叔. 这一场,主讲python的进程和线程. 目的:掌握初学必须的进程和线程知识. 进程和线程的区别和联系 终于开始加深难度,来到进程和线程的知识点~ 单就这两个 ...

随机推荐

  1. tip1:学习使用mybatis中使用mysql数据库的基本操作

    1.查看mysql服务是否启动: 2.root用户链接数据库:mysql -u root -p,随后输入正确的密码即可. 3.root用户创建数据库: 4.查看已建数据库:show databases ...

  2. netty系列之:Bootstrap,ServerBootstrap和netty中的实现

    目录 简介 Bootstrap和ServerBootstrap的联系 AbstractBootstrap Bootstrap和ServerBootstrap 总结 简介 虽然netty很强大,但是使用 ...

  3. MHA + Maxscale 数据库的高可用和读写分离

    MySQL 常见发行版本 MySQL 标准化.自动化部署 深入浅出MySQL备份与恢复 深入理解MySQL主从复制 MySQL构架设计与容量规划 MHA Maxscale MySQL 常见发行版本 M ...

  4. 防世界之NaNNaNNaNNaN-Batman

    题目: 只有一个附件,下载解压放到桌面. web应该是个html文件,改下后缀打开看看 发现就一个框和按钮,测试发现也没注入点,应该不是考sql.打开源码查看一下,发现是个js脚本,但是,代码是乱码, ...

  5. 从零开始,开发一个 Web Office 套件(5):Mouse hover over text

    <从零开始, 开发一个 Web Office 套件>系列博客目录 这是一个系列博客, 最终目的是要做一个基于HTML Canvas 的, 类似于微软 Office 的 Web Office ...

  6. 思迈特软件Smartbi:机器学习高深难懂?本文深入浅出给你讲明白!

    人工智能(Artificial Intelligence,缩写为AI)是对人的意识.思维过程进行模拟的一门新学科.如今,人工智能从虚无缥缈的科学幻想变成了现实.计算机科学家们在人工智能的技术核心--机 ...

  7. 别再用 Redis List 实现消息队列了,Stream 专为队列而生

    上回说到使用 Redis 的 List 实现消息队列有很多局限性,比如: 没有良好的 ACK 机制: 没有 ConsumerGroup 消费组概念: 消息堆积. List 是线性结构,想要查询指定数据 ...

  8. 基于隐私保护技术的DNS通信协议介绍

    本文提出了一种基于用户数据报协议的DNS传输中用户隐私保护的加密方法:DNSDEA.该方法采用PKI加密体系与DNS协议相融合,不仅解决了域名隐私保护问题,而且与传统DNS体系相兼容,保持了DNS系统 ...

  9. Oracle sqlplus 常用命令总结

    转至:https://blog.csdn.net/iteye_20746/article/details/81801309?utm_medium=distribute.pc_relevant.none ...

  10. linux(Centos7)安装mysql

    查看系统环境 [root@localhost html]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) CentOS 7 ...