0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

SQLx在Rust语言中的基础用法和进阶用法

科技绿洲 来源:TinyZ 作者:TinyZ 2023-09-19 14:32 次阅读

SQLx是一个Rust语言的异步SQL执行库,它支持多种数据库,包括MySQL、PostgreSQL、SQLite等。本教程将以MySQL数据库为例,介绍SQLx在Rust语言中的基础用法和进阶用法。

基础用法

要使用SQLx,需要在Cargo.toml文件中添加以下依赖:

[dependencies]
sqlx = { version = "0.6", features = ["mysql", "runtime-tokio-rustls"] }
tokio = { version = "1", features = ["full"] }

连接数据库

在使用SQLx之前,需要先连接数据库。SQLx提供了两种方式连接MySQL数据库:使用URL连接和使用配置文件连接。

URL连接

使用URL连接时,需要在代码中指定连接字符串,例如:

use sqlx::mysql::MySqlPoolOptions;

#[tokio::main]
async fn main() - > Result< (), sqlx::Error > {
    let pool = MySqlPoolOptions::new()
        .max_connections(5)
        .connect("mysql://username:password@hostname:port/database")
        .await?;
    // ...
    Ok(())
}

其中,usernamepassword是数据库用户名和密码,hostname是数据库主机名,port是数据库端口号,database是要连接的数据库名。

配置文件连接

使用配置文件连接时,需要在项目根目录下创建一个名为.env的文件,并在其中指定连接信息,例如:

DATABASE_URL=mysql://username:password@hostname:port/database

然后在代码中使用dotenv库加载.env文件,并使用sqlx::MySqlPool::connect_dotenv()方法连接数据库,例如:

use sqlx::mysql::MySqlPoolOptions;

#[tokio::main]
async fn main() - > Result< (), sqlx::Error > {
    dotenv::dotenv().ok();
    let pool = MySqlPoolOptions::new()
        .max_connections(5)
        .connect_dotenv()
        .await?;
    // ...
    Ok(())
}

查询数据

连接成功后,就可以使用SQLx执行SQL查询语句了。SQLx提供了两种方式执行SQL查询语句:使用query()方法和使用query_as()方法。

使用query()方法

使用query()方法执行SQL查询语句时,需要手动指定返回结果的类型,例如:

use sqlx::{MySqlPool, Row};

#[derive(Debug)]
struct User {
    id: i32,
    name: String,
}

#[tokio::main]
async fn main() - > Result< (), sqlx::Error > {
    let pool = MySqlPool::connect("mysql://username:password@hostname:port/database").await?;
    let mut conn = pool.acquire().await?;

    let mut rows = sqlx::query("SELECT id, name FROM users")
        .map(|row: sqlx::mysql::MySqlRow| {
            User {
                id: row.get(0),
                name: row.get(1),
            }
        })
        .fetch_all(&mut conn)
        .await?;

    for row in rows.iter() {
        println!("{:?}", row);
    }

    Ok(())
}

使用query_as()方法

使用query_as()方法执行SQL查询语句时,可以自动将返回结果转换为指定类型的结构体,例如:

use sqlx::{MySqlPool, FromRow};

#[derive(Debug, FromRow)]
struct User {
    id: i32,
    name: String,
}

#[tokio::main]
async fn main() - > Result< (), sqlx::Error > {
    let pool = MySqlPool::connect("mysql://username:password@hostname:port/database").await?;
    let mut conn = pool.acquire().await?;

    let mut rows = sqlx::query_as::< _, User >("SELECT id, name FROM users")
        .fetch_all(&mut conn)
        .await?;

    for row in rows.iter() {
        println!("{:?}", row);
    }

    Ok(())
}

插入数据

使用SQLx插入数据时,可以使用execute()方法或execute_with()方法。

使用execute()方法

使用execute()方法插入数据时,需要手动指定插入的数据,例如:

use sqlx::{MySqlPool, Row};

#[derive(Debug)]
struct User {
    name: String,
}

#[tokio::main]
async fn main() - > Result< (), sqlx::Error > {
    let pool = MySqlPool::connect("mysql://username:password@hostname:port/database").await?;
    let mut conn = pool.acquire().await?;

    let user = User {
        name: "John".to_string(),
    };

    let result = sqlx::query("INSERT INTO users (name) VALUES (?)")
        .bind(user.name)
        .execute(&mut conn)
        .await?;

    println!("{:?}", result);

    Ok(())
}

使用execute_with()方法

使用execute_with()方法插入数据时,可以使用结构体自动映射的特性,例如:

use sqlx::{MySqlPool, FromRow};

#[derive(Debug, FromRow)]
struct User {
    name: String,
}

#[tokio::main]
async fn main() - > Result< (), sqlx::Error > {
    let pool = MySqlPool::connect("mysql://username:password@hostname:port/database").await?;
    let mut conn = pool.acquire().await?;

    let user = User {
        name: "John".to_string(),
    };

    let result = sqlx::query_with::< _, User >("INSERT INTO users (name) VALUES (?)", user)
        .execute(&mut conn)
        .await?;

    println!("{:?}", result);

    Ok(())
}

更新数据

使用SQLx更新数据时,可以使用execute()方法或execute_with()方法。

使用execute()方法

使用execute()方法更新数据时,需要手动指定更新的条件和更新的数据,例如:

use sqlx::{MySqlPool, Row};

#[derive(Debug)]
struct User {
    id: i32,
    name: String,
}

#[tokio::main]
async fn main() - > Result< (), sqlx::Error > {
    let pool = MySqlPool::connect("mysql://username:password@hostname:port/database").await?;
    let mut conn = pool.acquire().await?;

    let user = User {
        id: 1,
        name: "John".to_string(),
    };

    let result = sqlx::query("UPDATE users SET name = ? WHERE id = ?")
        .bind(user.name)
        .bind(user.id)
        .execute(&mut conn)
        .await?;

    println!("{:?}", result);

    Ok(())
}

使用execute_with()方法

使用execute_with()方法更新数据时,可以使用结构体自动映射的特性,例如:

use sqlx::{MySqlPool, FromRow};

#[derive(Debug, FromRow)]
struct User {
    id: i32,
    name: String,
}

#[tokio::main]
async fn main() - > Result< (), sqlx::Error > {
    let pool = MySqlPool::connect("mysql://username:password@hostname:port/database").await?;
    let mut conn = pool.acquire().await?;

    let user = User {
        id: 1,
        name: "John".to_string(),
    };

    let result = sqlx::query_with::< _, User >("UPDATE users SET name = :name WHERE id = :id", user)
        .execute(&mut conn)
        .await?;

    println!("{:?}", result);

    Ok(())
}

删除数据

使用SQLx删除数据时,可以使用execute()方法或execute_with()方法。

使用execute()方法

使用execute()方法删除数据时,需要手动指定删除的条件,例如:

use sqlx::{MySqlPool, Row};

#[tokio::main]
async fn main() - > Result< (), sqlx::Error > {
    let pool = MySqlPool::connect("mysql://username:password@hostname:port/database").await?;
    let mut conn = pool.acquire().await?;

    let result = sqlx::query("DELETE FROM users WHERE id = ?")
        .bind(1)
        .execute(&mut conn)
        .await?;

    println!("{:?}", result);

    Ok(())
}

使用execute_with()方法

使用execute_with()方法删除数据时,可以使用结构体自动映射的特性,例如:

use sqlx::{MySqlPool, FromRow};

#[derive(Debug, FromRow)]
struct User {
    id: i32,
}

#[tokio::main]
async fn main() - > Result< (), sqlx::Error > {
    let pool = MySqlPool::connect("mysql://username:password@hostname:port/database").await?;
    let mut conn = pool.acquire().await?;

    let user = User {
        id: 1,
    };

    let result = sqlx::query_with::< _, User >("DELETE FROM users WHERE id = :id", user)
        .execute(&mut conn)
        .await?;

    println!("{:?}", result);

    Ok(())
}

进阶用法

事务

使用SQLx执行事务时,可以使用begin()方法开始事务,使用commit()方法提交事务,使用rollback()方法回滚事务。

use sqlx::{MySqlPool, Transaction};

#[derive(Debug)]
struct User {
    name: String,
}

#[tokio::main]
async fn main() - > Result< (), sqlx::Error > {
    let pool = MySqlPool::connect("mysql://username:password@hostname:port/database").await?;
    let mut conn = pool.acquire().await?;

    let mut tx = conn.begin().await?;

    let user = User {
        name: "John".to_string(),
    };

    let result = sqlx::query("INSERT INTO users (name) VALUES (?)")
        .bind(user.name)
        .execute(&mut tx)
        .await?;

    println!("{:?}", result);

    tx.commit().await?;

    Ok(())
}

连接池

使用SQLx连接池时,可以使用PoolOptions::new()方法创建连接池,并使用acquire()方法获取连接。

use sqlx::{MySqlPool, PoolOptions};

#[tokio::main]
async fn main() - > Result< (), sqlx::Error > {
    let pool = MySqlPool::connect("mysql://username:password@hostname:port/database").await?;
    let mut conn = pool.acquire().await?;

    let pool = MySqlPool::builder()
        .max_size(5)
        .build("mysql://username:password@hostname:port/database")
        .await?;

    let mut conn = pool.acquire().await?;

    // ...

    Ok(())
}

总结

本教程介绍了SQLx在Rust语言中的基础用法和进阶用法,包括连接数据库、查询数据、插入数据、更新数据、删除数据、事务和连接池等。SQLx是一个简单易用的异步SQL执行库,可以帮助Rust开发者快速地与多种数据库进行交互。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • SQL
    SQL
    +关注

    关注

    1

    文章

    738

    浏览量

    43462
  • 数据库
    +关注

    关注

    7

    文章

    3591

    浏览量

    63373
  • 文件
    +关注

    关注

    1

    文章

    540

    浏览量

    24402
  • 代码
    +关注

    关注

    30

    文章

    4556

    浏览量

    66784
  • rust语言
    +关注

    关注

    0

    文章

    58

    浏览量

    2958
  • SQLx
    +关注

    关注

    0

    文章

    2

    浏览量

    30
收藏 人收藏

    评论

    相关推荐

    SQLx的基础用法进阶用法

    SQLx是一个Rust语言的异步SQL数据库访问库,支持多种数据库,包括PostgreSQL、MySQL、SQLite等。本教程将以SQLite为例,介绍SQLx的基础
    的头像 发表于 09-19 14:29 1247次阅读

    Stream模块的基础用法进阶用法

    Rust 语言中,Tokio 是一个非常流行的异步编程框架。它提供了一系列的模块,其中最常用的就是 Stream 模块。Stream 模块允许我们以异步的方式处理数据流,这在很多情况下非常
    的头像 发表于 09-19 15:33 711次阅读

    基于Rust语言Hash特征的基础用法进阶用法

    ,包括Hash trait、HashMap、HashSet等,本教程将详细介绍Rust语言Hash特征的基础用法进阶用法。 基础
    的头像 发表于 09-19 16:02 741次阅读

    Rust语言如何与 InfluxDB 集成

    的数据处理和存储能力。 本教程将介绍 Rust 语言如何与 InfluxDB 集成,包括基础用法进阶用法和完整的示例代码。 基础
    的头像 发表于 09-30 16:45 618次阅读

    Rust的 match 语句用法

    执行不同的代码,这在处理复杂的逻辑时非常有用。在本教程中,我们将深入了解 Rust 的 match 语句,包括基础用法进阶用法和实践经验等方面。 基础
    的头像 发表于 09-19 17:08 657次阅读

    AsyncRead和AsyncWrite 模块进阶用法示例

    Rust 语言是一门高性能、安全、并发的编程语言,越来越受到开发者的关注和喜爱。而 Tokio 是 Rust 语言中一个非常流行的异步运行时
    的头像 发表于 09-20 11:41 533次阅读

    单片机的C语言中位操作用法

    单片机的C语言中位操作用法
    发表于 08-17 15:04

    C语言中atoi()函数的用法 相关资料分享

    C语言中atoi()函数的用法
    发表于 07-01 08:12

    C语言中的#和##的用法

    和conStr的参数,并且宏conStr和toString中均含有#或者##符号,所以A不能被解引用。导致不符合预期的情况出现。 3.2 解决方案 结果: 责任编辑:xj 原文标题:C语言中#和##的用法 文章出处:【微信公众号:嵌入式ARM】欢迎添加关注!文章转载请注明
    的头像 发表于 12-06 09:34 7.5w次阅读
    C<b class='flag-5'>语言中</b>的#和##的<b class='flag-5'>用法</b>

    C语言中的typedef的用法

    在以前的学习中对于C语言中typedef和define的认识是,#define是宏,作用是简单的替换,而typedef也是替换,只不过比define高级的是在替换的时候会进行语法检查。但是后来
    发表于 01-13 13:36 0次下载
    C<b class='flag-5'>语言中</b>的typedef的<b class='flag-5'>用法</b>

    详解C语言中特殊用法

    C语言有很多特殊的用法,如果这些特殊用法使用得当,会是你的代码变得更加有健壮,更加容易维护。
    的头像 发表于 07-15 08:57 1162次阅读

    【C语言进阶】C语言指针的高阶用法

    【C语言进阶】C语言指针的高阶用法
    的头像 发表于 08-31 13:24 1956次阅读

    基于select!宏的进阶用法

    Tokio 是一个基于 Rust 语言的异步编程框架,它提供了一组工具和库,使得异步编程变得更加容易和高效。其中最重要的组件之一就是 select!宏。 select!宏是 Tokio 中的一个核心
    的头像 发表于 09-19 15:35 316次阅读

    Rust语言中r2d2基础用法

    r2d2是Rust语言的一个连接池模块,可以用于管理和复用数据库连接。它可以与多种数据库进行交互,包括MySQL、PostgreSQL、SQLite等等。使用r2d2可以提高数据库操作的效率,避免
    的头像 发表于 09-19 16:25 1385次阅读

    元组的基础用法进阶用法

    元组是 Rust 语言中一种非常有用的数据结构,它可以将多个不同类型的值组合在一起。本教程将介绍元组的基础用法进阶用法,并结合示例代码进行
    的头像 发表于 09-30 16:49 546次阅读