Rust-Sqlx極簡教程


簡介

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

引用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM