• RustSqlx极简教程


    简介

    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

    引用

  • 相关阅读:
    统计学习方法学习笔记(一)--极大似然估计与贝叶斯估计原理及区别
    数据过拟合解决方法
    LSTM基础
    异方差产生与解决
    人工免疫相关算法
    Svm相关
    sscanf,sscanf_s及其相关用法
    C语言数组初始化
    生产者和消费者
    Linux线程-创建
  • 原文地址:https://www.cnblogs.com/Naylor/p/16062584.html
Copyright © 2020-2023  润新知