最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

  • mysql 單一驅(qū)動(dòng)
  • sqlx 多驅(qū)動(dòng),異步,不是ORM
  • diesel 多驅(qū)動(dòng),異常,ORM

因?yàn)?code>mysql的crate有點(diǎn)單一,這里主要是說(shuō)明sqlxdiesel的使用,分兩篇記錄。本都吃是以sqlx為說(shuō)明

在這過(guò)程的走了不少不能言語(yǔ)的彎路主要有以下兩點(diǎn):

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

sqlx的sql是原始的,我所知道的是它不像ORM那樣,能通過(guò)一系列的方法組合成相應(yīng)的sql,sql都是手寫(xiě)的。是不是用ORM,看自己的需求進(jìn)行選擇

crate 依賴(lài)(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"

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

方式1:原始操作方面

通過(guò)下標(biāo)來(lái)獲取數(shù)據(jù)

.env文件內(nèi)容

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

main.rs文件內(nèi)容

use chrono::{NaiveDateTime};    // 處理 數(shù)據(jù)庫(kù)中 datetime 類(lèi)型
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ù)據(jù)庫(kù)中 json 類(lèi)型
use rust_decimal::Decimal;      // 處理 數(shù)據(jù)庫(kù)中 decimal 類(lèi)型

#[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("沒(méi)有設(shè)置數(shù)據(jù)信息");
    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(())
}

單純的查詢(xún)出來(lái)的 rows 數(shù)據(jù)打印出來(lái)有點(diǎn)初一看看不明白,沒(méi)有直觀性的 key=>value 的形式,感覺(jué)是因?yàn)閺?qiáng)類(lèi)的原因,不能單純的當(dāng)做 String=>String 來(lái)處理,所以數(shù)據(jù)庫(kù)中的類(lèi)型也要與rust中的類(lèi)型相一一對(duì)應(yīng)。上面的代碼是通過(guò)索引(get)的方法來(lái)獲取相應(yīng)的值,這個(gè)方法依賴(lài) Row trait,這個(gè)是關(guān)鍵

處理后的數(shù)據(jù)

[
    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ù)據(jù)

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,通過(guò)結(jié)構(gòu)體自動(dòng)轉(zhuǎn)化

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

代碼量減少的同時(shí)還更加符合人性化,這種使用方法相當(dāng)不錯(cuò),推薦使用,要注意點(diǎn)是查詢(xún)出來(lái)的字段一定要多于結(jié)構(gòu)的字段

結(jié)構(gòu)變化(部分)

#[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,
}

查詢(xún)部分

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

結(jié)果

[
    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:使用宏方法

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

部分代碼

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

結(jié)果

[
    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,
        ),
    },
]

關(guān)于 execute

上面說(shuō)的都是 query 也就是增刪改查中的查。查關(guān)注的點(diǎn)是數(shù)據(jù),增刪改關(guān)注的點(diǎn)是影響數(shù)量,使用的方法很簡(jiǎn)單,只返回影響的數(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);

對(duì)應(yīng)的結(jié)果

MySqlQueryResult {
    rows_affected: 1,
    last_insert_id: 5,
}

MySqlQueryResult {
    rows_affected: 1,
    last_insert_id: 0,
}

總的來(lái)說(shuō),查詢(xún)常用的方法就兩個(gè) fetch_all 及 fetch_one 上面用的都是 fetch_all ,fetch_one的用法同時(shí)。而對(duì)于增刪改則只有一個(gè)execute方法。

小小問(wèn)題

多數(shù)情況下sql是有條件參數(shù)的,條件一多,手動(dòng)組合sql會(huì)有點(diǎn)麻煩,那么對(duì)于sqlx來(lái)說(shuō),怎么處理會(huì)比較好?

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

相關(guān)文章

  • Rust?語(yǔ)言println!?宏的格式占位符詳解

    Rust?語(yǔ)言println!?宏的格式占位符詳解

    這篇文章主要介紹了Rust語(yǔ)言的println!宏的格式占位符,這只是格式說(shuō)明符的一部分清單,Rust?的格式化系統(tǒng)非常靈活和強(qiáng)大,支持更多的選項(xiàng)和組合,需要的朋友可以參考下
    2024-03-03
  • Rust字符串深度解析String與str的問(wèn)題小結(jié)

    Rust字符串深度解析String與str的問(wèn)題小結(jié)

    在Rust編程語(yǔ)言中,字符串處理是一個(gè)核心概念,但與其他語(yǔ)言不同的是,Rust提供了兩種主要的字符串類(lèi)型:String和&str,本文介紹Rust字符串深度解析String與str的問(wèn)題,感興趣的朋友跟隨小編一起看看吧
    2026-03-03
  • Rust 中單線程 Web 服務(wù)器的實(shí)現(xiàn)

    Rust 中單線程 Web 服務(wù)器的實(shí)現(xiàn)

    本文用Rust構(gòu)建單線程Web服務(wù)器,通過(guò)HTTP/TCP處理請(qǐng)求,返回hello.html或404.html,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-06-06
  • Rust中的關(guān)聯(lián)類(lèi)型總結(jié)

    Rust中的關(guān)聯(lián)類(lèi)型總結(jié)

    關(guān)聯(lián)類(lèi)型是定義通用trait的一種機(jī)制。它允許在trait中定義一個(gè)或多個(gè)占位符類(lèi)型,這些類(lèi)型將在trait的實(shí)現(xiàn)中具體化。文中有詳細(xì)示例代碼供參考,需要的朋友可以閱讀一下
    2023-05-05
  • Rust中的函數(shù)指針詳解

    Rust中的函數(shù)指針詳解

    Rust是一種現(xiàn)代的系統(tǒng)編程語(yǔ)言,它支持函數(shù)指針。函數(shù)指針是指向函數(shù)的指針,可以將函數(shù)作為參數(shù)傳遞給其他函數(shù)或存儲(chǔ)在變量中。Rust中的函數(shù)指針可以用于實(shí)現(xiàn)回調(diào)函數(shù)、動(dòng)態(tài)分發(fā)和多態(tài)等功能。本文將介紹Rust中的函數(shù)指針的基本用法和高級(jí)用法。
    2023-05-05
  • 為什么要選Rust?學(xué)習(xí)Rust從零開(kāi)始配置和實(shí)現(xiàn)第一個(gè)簡(jiǎn)單項(xiàng)目

    為什么要選Rust?學(xué)習(xí)Rust從零開(kāi)始配置和實(shí)現(xiàn)第一個(gè)簡(jiǎn)單項(xiàng)目

    本文介紹了Rust語(yǔ)言的核心價(jià)值、應(yīng)用場(chǎng)景、開(kāi)發(fā)環(huán)境搭建、第一個(gè)Rust項(xiàng)目的創(chuàng)建與擴(kuò)展、調(diào)試、發(fā)布流程,以及新手常見(jiàn)陷阱與避坑方法,通過(guò)學(xué)習(xí)Rust,開(kāi)發(fā)者可以實(shí)現(xiàn)高效且安全的系統(tǒng)級(jí)開(kāi)發(fā)、網(wǎng)絡(luò)編程和工具開(kāi)發(fā)
    2026-01-01
  • 深入了解Rust?結(jié)構(gòu)體的使用

    深入了解Rust?結(jié)構(gòu)體的使用

    結(jié)構(gòu)體是一種自定義的數(shù)據(jù)類(lèi)型,它允許我們將多個(gè)不同的類(lèi)型組合成一個(gè)整體。下面我們就來(lái)學(xué)習(xí)如何定義和使用結(jié)構(gòu)體,并對(duì)比元組與結(jié)構(gòu)體之間的異同,需要的可以參考一下
    2022-11-11
  • Rust常用功能實(shí)例代碼匯總

    Rust常用功能實(shí)例代碼匯總

    通過(guò)一系列實(shí)用示例展示了Rust在文件操作、網(wǎng)絡(luò)請(qǐng)求、并發(fā)編程、命令行工具以及數(shù)據(jù)庫(kù)操作等方面的應(yīng)用,這些示例不僅展示了 Rust 的強(qiáng)大功能,還提供了實(shí)際開(kāi)發(fā)中的指導(dǎo)和參考,通過(guò)這些示例,您可以更好地理解 Rust 的特性,并將其應(yīng)用于您的項(xiàng)目中
    2024-12-12
  • rust中的match表達(dá)式使用詳解

    rust中的match表達(dá)式使用詳解

    在rust中提供了一個(gè)極為強(qiáng)大的控制流運(yùn)算符match,這篇文章主要介紹了rust中的match表達(dá)式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • rust 一個(gè)日志緩存記錄的通用實(shí)現(xiàn)方法

    rust 一個(gè)日志緩存記錄的通用實(shí)現(xiàn)方法

    本文給出了一個(gè)通用的設(shè)計(jì)模式,通過(guò)建造者模式實(shí)例化記錄對(duì)象,可自定義格式化器將實(shí)例化后的記錄對(duì)象寫(xiě)入到指定的緩存對(duì)象中,這篇文章主要介紹了rust 一個(gè)日志緩存記錄的通用實(shí)現(xiàn)方法,需要的朋友可以參考下
    2024-04-04

最新評(píng)論

松江区| 灵川县| 汉中市| 西乌| 沭阳县| 金溪县| 新晃| 马龙县| 柞水县| 元朗区| 叶城县| 天津市| 铜鼓县| 敦化市| 茌平县| 左云县| 清远市| 柏乡县| 临高县| 岐山县| 西乡县| 滨州市| 铜川市| 巴东县| 凌源市| 内乡县| 惠水县| 西盟| 利辛县| 页游| 佛山市| 宜川县| 临夏县| 寻乌县| 郓城县| 临高县| 钟祥市| 漯河市| 新化县| 枝江市| 建宁县|