欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Rust使用Sqlx連接Mysql的實現(xiàn)

 更新時間:2024年03月14日 10:44:49   作者:L_Qiu  
數(shù)據庫在編程中是一個很重要的環(huán)節(jié),本文主要介紹了Rust使用Sqlx連接Mysql的實現(xiàn),記錄rust如何操作數(shù)據庫并以mysql為主的做簡單的使用說明,感興趣的可以了解一下

數(shù)據庫在編程中是一個很重要的環(huán)節(jié),這里是記錄rust如何操作數(shù)據庫并以mysql為主的做簡單的使用說明。rust中對mysql數(shù)據庫存有支持的我所知道的crate:

  • mysql 單一驅動
  • sqlx 多驅動,異步,不是ORM
  • diesel 多驅動,異常,ORM

因為mysqlcrate有點單一,這里主要是說明sqlxdiesel的使用,分兩篇記錄。本都吃是以sqlx為說明

在這過程的走了不少不能言語的彎路主要有以下兩點:

  • 文檔都是英文,多數(shù)都是偏向于postgres(英文不好)
  • select出來的數(shù)據不直觀。不像php那樣直接一個關聯(lián)數(shù)據解決所有問題

sqlx的sql是原始的,我所知道的是它不像ORM那樣,能通過一系列的方法組合成相應的sql,sql都是手寫的。是不是用ORM,看自己的需求進行選擇

crate 依賴(Cargo.toml文件)

[dependencies]
tokio = { version = "1", features = ["full"] }
sqlx = { version = "0.6", features = [ 
    "runtime-tokio-native-tls", 
    "mysql", 
    "chrono", 
    "json",
    "macros",
    "decimal"
] }
dotenvy = "0.15.6"
chrono = { version = "0.4.23", features = ["serde"] }
sqlx-cli = "0.6.2"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
rust_decimal = "1.28.0"

這里我使用的運行時是tokio,它好像支持三種運行時,另外兩種是Async-std(runtime-async-std-native-tls),Actix-web(runtime-actix-native-tls),不同的運行里相應的要在sqlx開啟相應的特性支持。在這里有一個很重要的特性macros,如果大量使用宏也就是query*!,而且也非常方面查詢,可以讓我獲取類似php中操作數(shù)據庫的感覺,所以這個特性很重要。

方式1:原始操作方面

通過下標來獲取數(shù)據

.env文件內容

DATABASE_URL=mysql://root:root@localhost:3306/test

main.rs文件內容

use chrono::{NaiveDateTime};    // 處理 數(shù)據庫中 datetime 類型
use sqlx::Row;                  // get 方法的 trait
use sqlx::mysql::{MySqlRow, MySqlPoolOptions};
use dotenvy::dotenv;
use std::{env};
use serde::{Deserialize, Serialize};
use serde_json::Value;          // 處理 數(shù)據庫中 json 類型
use rust_decimal::Decimal;      // 處理 數(shù)據庫中 decimal 類型

#[derive(Debug)]
struct RawRawData {
    id: i32, 
    title: String,
    subtitle: String,
    content: String,
    tag: Value,
    create_time: NaiveDateTime,
    normal_time: i32,
    vip_pay: Decimal,
    normal_pay: f32,
}

#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
    dotenv().ok();

    let url = env::var("DATABASE_URL").expect("沒有設置數(shù)據信息");
    let pool = MySqlPoolOptions::new().connect(&url).await?;
    
    let rows: Vec<MySqlRow> = sqlx::query("select id,title from test").fetch_all(&pool).await?;

    let mut data: Vec<RawRawData> = vec![];

    for row in rows.iter() {
        let id: i32 = row.get(0);
        let title: String = row.get(1);
        let subtitle: String = row.get(2);
        let content: String = row.get(3);
        let tag: Value = row.get(4);
        let create_time: NaiveDateTime = row.get(5);
        let normal_time: i32 = row.get(6);
        let vip_pay: Decimal = row.get(7);
        let normal_pay: f32 = row.get(8);
        data.push(RawRawData{
            id,
            title,
            subtitle,
            content,
            tag,
            create_time,
            normal_time,
            vip_pay,
            normal_pay
        });
    }

    Ok(())
}

單純的查詢出來的 rows 數(shù)據打印出來有點初一看看不明白,沒有直觀性的 key=>value 的形式,感覺是因為強類的原因,不能單純的當做 String=>String 來處理,所以數(shù)據庫中的類型也要與rust中的類型相一一對應。上面的代碼是通過索引(get)的方法來獲取相應的值,這個方法依賴 Row trait,這個是關鍵

處理后的數(shù)據

[
    RawRawData {
        id: 1,
        title: "111",
        subtitle: "1111",
        content: "11111",
        tag: Array [],
        create_time: 2023-02-02T03:06:17,
        normal_time: 1675278415,
        vip_pay: 10.20,
        normal_pay: 10.0,
    },
    RawRawData {
        id: 2,
        title: "2222",
        subtitle: "222",
        content: "2222",
        tag: Array [
            String("111"),
            String("222"),
        ],
        create_time: 2023-02-02T03:06:17,
        normal_time: 1675278415,
        vip_pay: 10.20,
        normal_pay: 10.0,
    },
]

原始數(shù)據

MySqlRow { row: Row { storage: b"\0\0\x01\0\0\0\x03111\x041111\x0511111\x02[]\x07\xe7\x07\x02\x02\x03\x06\x11O\xb8\xdac\x0510.20\0\0 A", values: [Some(2..6), Some(7..10), Some(11..15), Some(16..21), Some(22..24), Some(24..32), Some(32..36), Some(37..42), Some(42..46)] }, format: Binary, columns: [MySqlColumn { ordinal: 0, name: id, type_info: MySqlTypeInfo { type: Long, flags: NOT_NULL | PRIMARY_KEY | AUTO_INCREMENT, char_set: 63, max_size: Some(11) }, flags: Some(NOT_NULL | PRIMARY_KEY | AUTO_INCREMENT) }, MySqlColumn { ordinal: 1, name: title, type_info: MySqlTypeInfo { type: String, flags: (empty), char_set: 224, max_size: Some(80) }, flags: Some((empty)) }, MySqlColumn { ordinal: 2, name: subtitle, type_info: MySqlTypeInfo { type: VarString, flags: (empty), char_set: 224, max_size: Some(1020) }, flags: Some((empty)) }, MySqlColumn { ordinal: 3, name: content, type_info: MySqlTypeInfo { type: Blob, flags: BLOB, char_set: 224, max_size: Some(262140) }, flags: Some(BLOB) }, MySqlColumn { ordinal: 4, name: tag, type_info: MySqlTypeInfo { type: Json, flags: BLOB | BINARY, char_set: 63, max_size: Some(4294967295) }, flags: Some(BLOB | BINARY) }, MySqlColumn { ordinal: 5, name: create_time, type_info: MySqlTypeInfo { type: Datetime, flags: BINARY, char_set: 63, max_size: Some(19) }, flags: Some(BINARY) }, MySqlColumn { ordinal: 6, name: normal_time, type_info: MySqlTypeInfo { type: Long, flags: (empty), char_set: 63, max_size: Some(11) }, flags: Some((empty)) }, MySqlColumn { ordinal: 7, name: vip_pay, type_info: MySqlTypeInfo { type: NewDecimal, flags: (empty), char_set: 63, max_size: Some(12) }, flags: Some((empty)) }, MySqlColumn { ordinal: 8, name: normal, type_info: MySqlTypeInfo { type: Float, flags: (empty), char_set: 63, max_size: Some(10) }, flags: Some((empty)) }], column_names: {title: 1, id: 0, content: 3, vip_pay: 7, create_time: 5, subtitle: 2, tag: 4, normal_time: 6, normal: 8} }]

方法2,通過結構體自動轉化

索引這個方法,在字段少的情況下還行,多的時間,代碼量多,還要 for 二次處理,不是很方便。在已定義的結構中 RawRawData 所要的字段及對應的類型都有了,我們只要為它加一個 sqlx::FromRow 特性就可再配合 query_as 方法就可以實現(xiàn)自動轉化,達到想要的效果。

代碼量減少的同時還更加符合人性化,這種使用方法相當不錯,推薦使用,要注意點是查詢出來的字段一定要多于結構的字段

結構變化(部分)

#[derive(Debug, sqlx::FromRow)]
struct RawRawData {
    id: i32, 
    title: String,
    subtitle: String,
    content: String,
    tag: Value,
    create_time: NaiveDateTime,
    normal_time: i32,
    vip_pay: Decimal,
    normal_pay: f32,
}

查詢部分

let data = sqlx::query_as::<_, RawRawData>("select * from test").fetch_all(&pool).await?;
println!("{:?}", data);

結果

[
    RawRawData {
        id: 1,
        title: "111",
        subtitle: "1111",
        content: "11111",
        tag: Array [],
        create_time: 2023-02-02T03:06:17,
        normal_time: 1675278415,
        vip_pay: 10.20,
        normal_pay: 10.0,
    },
    RawRawData {
        id: 2,
        title: "2222",
        subtitle: "222",
        content: "2222",
        tag: Array [
            String("111"),
            String("222"),
        ],
        create_time: 2023-02-02T03:06:17,
        normal_time: 1675278415,
        vip_pay: 10.20,
        normal_pay: 10.0,
    },
]

方法3:使用宏方法

宏方法查詢來的結果不需要由手動轉化,是一種比較接近 php 關聯(lián)查詢來的結果??梢酝ㄟ^字段名直接訪問數(shù)據,要注意的一點是,它有很多數(shù)據類型的值都是 Option 類型(我這邊除了主鍵是數(shù)字,其它都是 Option),主要有兩個方法 query! 及 query_as!

部分代碼

let rows = sqlx::query!("select * from test")
        .fetch_all(&pool).await?;
println!("{:#?}", rows);

結果

[
    Record {
        id: 1,
        title: Some(
            "111",
        ),
        subtitle: Some(
            "1111",
        ),
        content: Some(
            "11111",
        ),
        tag: Some(
            Array [],
        ),
        create_time: Some(
            2023-02-02T03:06:17,
        ),
        normal_time: Some(
            1675278415,
        ),
        vip_pay: Some(
            10.20,
        ),
        normal_pay: Some(
            10.0,
        ),
    },
    Record {
        id: 2,
        title: Some(
            "2222",
        ),
        ),
        create_time: Some(
            2023-02-02T03:06:17,
        ),
        normal_time: Some(
            1675278415,
        ),
        vip_pay: Some(
            10.20,
        ),
        normal_pay: Some(
            10.0,
        ),
    },
]

關于 execute

上面說的都是 query 也就是增刪改查中的查。查關注的點是數(shù)據,增刪改關注的點是影響數(shù)量,使用的方法很簡單,只返回影響的數(shù)量及最新插入的id

代碼

// 增加
let data = sqlx::query("INSERT INTO `test`.`test`(`id`, `title`, `subtitle`, `content`, `tag`, `create_time`, `normal_time`, `vip_pay`, `normal_pay`) VALUES (4, '2222', '222', '2222', '[\"111\", \"222\"]', '2023-02-02 03:06:17', 1675278415, 10.20, 10);
").execute(&pool).await?;
println!("{:#?}", data);

// 刪除
let data = sqlx::query("DELETE FROM `test` where id = ?")
.bind(4)
.execute(&pool).await?;
println!("{:#?}", data);

對應的結果

MySqlQueryResult {
    rows_affected: 1,
    last_insert_id: 5,
}

MySqlQueryResult {
    rows_affected: 1,
    last_insert_id: 0,
}

總的來說,查詢常用的方法就兩個 fetch_all 及 fetch_one 上面用的都是 fetch_all ,fetch_one的用法同時。而對于增刪改則只有一個execute方法。

小小問題

多數(shù)情況下sql是有條件參數(shù)的,條件一多,手動組合sql會有點麻煩,那么對于sqlx來說,怎么處理會比較好?

到此這篇關于Rust使用Sqlx連接Mysql的實現(xiàn)的文章就介紹到這了,更多相關Rust連接Mysql 內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Rust中的Option枚舉快速入門教程

    Rust中的Option枚舉快速入門教程

    Rust中的Option枚舉用于表示可能不存在的值,提供了多種方法來處理這些值,避免了空指針異常,文章介紹了Option的定義、常見方法、使用場景以及注意事項,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • Rust 中的閉包之捕獲環(huán)境的匿名函數(shù)

    Rust 中的閉包之捕獲環(huán)境的匿名函數(shù)

    這篇文章介紹了Rust編程語言中的閉包,包括閉包的定義、使用、捕獲環(huán)境中的變量、類型推斷與注解、與函數(shù)的比較以及實際應用,閉包具有捕獲環(huán)境、類型推斷和高效性等特性,是Rust中一個非常強大的工具,感興趣的朋友一起看看吧
    2025-02-02
  • rust多個mod文件引用和文件夾mod使用注意事項小結

    rust多個mod文件引用和文件夾mod使用注意事項小結

    在 Rust 項目中,可以使用 mod 關鍵字將一個文件夾或一個 rs 文件作為一個模塊引入到當前文件中,本文給大家介紹rust多個mod文件引用和文件夾mod使用注意事項小結,感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • Rust錯誤處理之`foo(...)?`的用法與錯誤類型轉換小結

    Rust錯誤處理之`foo(...)?`的用法與錯誤類型轉換小結

    foo(...)?語法糖為Rust的錯誤處理提供了極大的便利,通過結合map_err方法和From?trait的實現(xiàn),你可以輕松地處理不同類型的錯誤,并保持代碼的簡潔性和可讀性,這篇文章主要介紹了Rust錯誤處理:`foo(...)?`的用法與錯誤類型轉換,需要的朋友可以參考下
    2024-05-05
  • Rust?語言println!?宏的格式占位符詳解

    Rust?語言println!?宏的格式占位符詳解

    這篇文章主要介紹了Rust語言的println!宏的格式占位符,這只是格式說明符的一部分清單,Rust?的格式化系統(tǒng)非常靈活和強大,支持更多的選項和組合,需要的朋友可以參考下
    2024-03-03
  • rust語言基礎pub關鍵字及Some語法示例

    rust語言基礎pub關鍵字及Some語法示例

    這篇文章主要為大家介紹了rust語言基礎pub關鍵字及Some語法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • Rust中的derive屬性示例詳解

    Rust中的derive屬性示例詳解

    derive屬性的出現(xiàn)解決了手動實現(xiàn)一些特性時需要編寫大量重復代碼的問題,它可以讓編譯器自動生成這些特性的基本實現(xiàn),從而減少了程序員需要編寫的代碼量,這篇文章主要介紹了Rust中的derive屬性詳解,需要的朋友可以參考下
    2023-04-04
  • Rust動態(tài)調用字符串定義的Rhai函數(shù)方式

    Rust動態(tài)調用字符串定義的Rhai函數(shù)方式

    Rust中使用Rhai動態(tài)調用字符串定義的函數(shù),通過eval_expression_with_scope實現(xiàn),但參數(shù)傳遞和函數(shù)名處理有局限性,使用FnCall功能更健壯,但更復雜,總結提供了更通用的方法,但需要處理更多錯誤情況
    2025-02-02
  • Rust中的Copy和Clone對比分析

    Rust中的Copy和Clone對比分析

    這篇文章主要介紹了Rust中的Copy和Clone及區(qū)別對比分析,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • C++的替代:微軟如何使用rust?

    C++的替代:微軟如何使用rust?

    這篇文章主要介紹了微軟如何使用rust的,幫助大家了解c++和rust這兩門編程語言的聯(lián)系與區(qū)別,感興趣的朋友可以了解下
    2020-09-09

最新評論