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

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

3天内不再提示

如何在Rust中连接和使用MySQL数据库

科技绿洲 来源:TinyZ 作者:TinyZ 2023-09-30 17:05 次阅读

MySQL是一个广泛使用的关系型数据库,Rust作为一门相对较新的系统级编程语言,具有C语言般的高性能、安全、并发等特性,因此与MySQL一起使用是一种非常有趣的选择。在本教程中,我们将手把手地展示如何在Rust中连接和使用MySQL数据库。

安装 mysql 模块

这里我们假设你已经安装了Rust编程语言工具链,在本教程中,我们将使用mysql crate来连接和使用MySQL数据库。要安装mysql crate,我们可以使用Rust语言包管理器cargo,只需在终端中输入以下命令:

cargo install mysql

安装成功后,我们可以开始尝试连接MySQL数据库了。

连接MySQL数据库

首先,我们需要安装和配置MySQL数据库,以便在Rust程序中进行连接。安装和配置MySQL在此处不做叙述。

在Rust程序中使用mysql crate库连接MySQL数据库,需要进行以下步骤:

    1. 导入mysql crate
    1. 使用mysql::OptsBuilder设置MySQL连接选项
    1. 使用mysql::Pool::new创建MySQL连接池
    1. 使用pool.get_conn()获取MySQL连接,并进行一些操作,例如插入、查询等
    1. 使用pool.disconnect()断开MySQL连接

下面是连接MySQL数据库的示例代码:

use mysql::*;

fn main() {
    let opts = OptsBuilder::new()
        .ip_or_hostname(Some("localhost"))
        .user(Some("root"))
        .pass(Some("password"))
        .db_name(Some("test"))
        .tcp_port(3306);

    let pool = Pool::new(opts).unwrap();
    let mut conn = pool.get_conn().unwrap();

    let result = conn.query_first("SELECT * FROM users").unwrap();
    for row in result {
        let name: String = row.get("name").unwrap();
        let age: i32 = row.get("age").unwrap();
        println!("{} is {} years old", name, age);
    }

    pool.disconnect().unwrap();
}

以上代码创建了一个MySQL连接池,并从连接池中获取一个MySQL连接,查询了一个名为users的表,并将结果作为元素进行遍历。

Rust使用MySQL的进阶用法

事务(Transaction)

为了保证MySQL数据库中的数据一致性,我们通常需要使用事务(Transaction)。在Rust中,可以使用MySQL的事务功能并结合mysql::Transaction来实现。

使用以下代码示例可以体验事务的实现:

use mysql::*;

fn main() {
    let opts = OptsBuilder::new()
        .ip_or_hostname(Some("localhost"))
        .user(Some("root"))
        .pass(Some("password"))
        .db_name(Some("test"))
        .tcp_port(3306);

    let pool = Pool::new(opts).unwrap();
    let mut conn = pool.get_conn().unwrap();

    // Start a transaction
    let mut transaction = conn.start_transaction(TxOpts::default()).unwrap();

    // Insert data into a table
    transaction .prep_exec("INSERT INTO users (name, age) VALUES (?, ?)", ("Alice", 23)).unwrap();
    transaction.prep_exec("INSERT INTO users (name, age) VALUES (?, ?)", ("Bob", 25)).unwrap();

    // Commit a transaction
    transaction.commit().unwrap();

    // Select data from a table let result = conn.query("SELECT * FROM users").unwrap();
    for row in result {
        let name: String = row.get("name").unwrap();
        let age: i32 = row.get("age").unwrap();
        println!("{} is {} years old", name, age);
    }

    pool.disconnect().unwrap();
}

以上代码创建了一个名为users的表,并在事务内分别插入了两个元素,数据被成功提交到了MySQL数据库,我们看到了名为AliceBob的条目。

异步IO

Rust语言具有异步IO处理的优势。在Rust中使用MySQL异步IO时,可以使用tokio-mysql crate来实现。tokio-mysql crate是一个基于Tokio实现的异步MySQL数据库客户端。

下面是使用tokio-mysql crate的示例代码:

use std::str::FromStr;

use tokio::runtime::Builder;
use tokio::time::Duration;
use tokio_mysql::{prelude::*, Error, Opts, Pool};

#[tokio::main]
async fn main() - > Result< (), Error > {
    let opts = Opts::from_url("mysql://root:password@localhost:3306/test")?;
    let pool = Pool::new(opts);

    let pool = match pool {
        Ok(p) = > p,
        Err(e) = > return Err(e),
    };

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

    conn.query_drop("CREATE TABLE IF NOT EXISTS students (
            id INT PRIMARY KEY NOT NULL,
            name TEXT NOT NULL,
            age INT NOT NULL
        )")
        .await?;

    let id = 1;
    let name = "Alice";
    let age = 23;

    conn.exec_drop(
            format!(
                "INSERT INTO students (id, name, age) VALUES ({}, "{}", {})",
                id, name, age
            )
            .as_str()
        )
        .await?;

    let mut conn2 = pool.get_conn().await?;
    let result = conn2
        .query_iter(
            String::from("SELECT * FROM students")
                .as_str(),
        )
        .await?;

    for row in result {
        let id: u32 = row.unwrap().take("id").unwrap().as_integer().unwrap().try_into().unwrap();
        let name: &str = row.unwrap().take("name").unwrap().as_sql_str();
        let age: u32 = row.unwrap().take("age").unwrap().as_integer().unwrap().try_into().unwrap();

        println!("{} is {} years old", name, age);
    }

    Ok(())
}

它创建了一个名为students的表,并插入了一个名为Alice年龄为23的元素,然后遍历该表并打印结果。

Rust使用MySQL的最佳实践

连接池

在连接MySQL数据库时,使用连接池是非常重要的。连接池是一个预先创建的连接集合,由于预先初始化了这些连接,因此在保持连接上下文的情况下执行多个操作变得更加轻松。在Rust中使用mysql::Pool连接MySQL数据库是非常常见的。

let opts = OptsBuilder::new()
    .ip_or_hostname(Some("localhost"))
    .user(Some("root"))
    .pass(Some("password"))
    .db_name(Some("test"))
    .tcp_port(3306);

let pool = Pool::new(opts).unwrap();

避免SQL注入

避免SQL注入攻击是一个重要的安全问题。在Rust中使用mysql crate,可以使用mysql::from_valuemysql::Value::from方法来避免SQL注入攻击。

在Rust中,需要使用以下代码实现SQL语句中的参数绑定:

let name = "Alice";
let age = 23;

conn.prep_exec("INSERT INTO students (name, age) VALUES (?, ?)", (name, age),).unwrap();

在将参数传递给SQL查询时,需要使用mysql::Value::from方法将变量转换为mysql::Value类型,以防止SQL注入攻击。要从mysql::Value转换回常规变量,可以使用mysql::from_value方法。使用以下示例代码:

use mysql::*;

fn main() {
    let result: Vec< Row > = conn.query("SELECT * FROM students WHERE age >= ?", (age.into(),)).unwrap();
    for row in result {
        let age: i32 = from_value(row.get("age").unwrap());
        let name: String = from_value(row.get("name").unwrap());
        println!("{} is {} years old", name, age);
    }
}

SQL执行和结果处理

在Rust中,可以使用mysql::Conn::querymysql::Conn::exec_itermysql::Conn::prep_exec等方法来执行SQL语句。但是,这些方法返回的结果类型有很大不同。query方法返回包含所有结果集的Vec类型,而exec_iter方法返回mysql::Row类型的迭代器。最后,prep_exec方法是最常用的方法,它可以绑定参数,并类似于通过命令行客户端发送的查询,并返回mysql::QueryResult类型。如果要提取单个结果,可以使用mysql::QueryResult的方法mysql::QueryResult::next来获取。

使用以下代码示例说明不同方法的使用:

use mysql::*;

fn main() {
    let result: Vec< Row > = conn.query("SELECT * FROM students WHERE age >= ?", (age.into(),)).unwrap();
    for row in result {
        let age: i32 = from_value(row.get("age").unwrap());
        let name: String = from_value(row.get("name").unwrap());
        println!("{} is {} years old", name, age);
    }

    let mut iter = conn.exec_iter("SELECT age FROM students WHERE name = "Alice"").unwrap();
    while let Some(result) = iter.next() {
        let age: i32 = from_value(result.unwrap());
        println!("Alice is {} years old", age);
    }

    conn.prep_exec("INSERT INTO students (name, age) VALUES (?, ?)",(name, age),).unwrap();
}

结论

本教程介绍了如何在Rust中连接和使用MySQL数据库。我们学习了使用mysql crate连接MySQL数据库,并实现了一些常见用例,例如事务、异步IO等。此外,我们使用连接池、避免SQL注入技巧,并使用了不同的SQL执行和结果处理方法。如果你正在使用Rust编程语言,那么通过学习本教程,你将掌握基本和高级的连接和使用MySQL技巧。

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

    关注

    180

    文章

    7530

    浏览量

    128665
  • 编程语言
    +关注

    关注

    9

    文章

    1878

    浏览量

    33108
  • 管理器
    +关注

    关注

    0

    文章

    233

    浏览量

    18315
  • MYSQL数据库
    +关注

    关注

    0

    文章

    95

    浏览量

    9277
  • Rust
    +关注

    关注

    1

    文章

    223

    浏览量

    6387
收藏 人收藏

    评论

    相关推荐

    labview有调用mysql数据库问题????

    labview有调用mysql数据库,请问labview打包成exe安装档,怎么把mysql数据库打包进来,是mysql
    发表于 05-19 16:17

    labview 连接mysql 数据库的问题

    `我根据网络上的教程想用labsql 做个连接mysql的vi,但是就是连接不上数据库。(已经新建数据源DSN)求教下,字符串 3,4 是不
    发表于 01-07 22:06

    labview连接mysql数据库的问题

    这个ODBC数据流已经成功设置了,为什么用labview连接mysql数据库就出现这个错误呢?望大神解答,谢谢啦!
    发表于 08-19 08:30

    labview无法将中文写入mysql数据库

    这个问题刚刚出现,我没有很深入地去调查,可能是一个小问题而已。labview向Mysql数据库写入数据时,英文、数字没问题,但是没有中文。也没有出现乱码,就是完全消失了。所以这也可能
    发表于 12-17 00:02

    mysql数据库设计步骤

    mysql数据库设计和优化
    发表于 05-13 11:00

    MySQL数据库使用

    关于MySQL数据库的简单操作
    发表于 10-24 14:32

    Python连接MySQL数据库及模块封装

    python连接mysql与sql server数据库及相应的模块封装
    发表于 05-01 16:06

    mySQL数据库介绍

    mySQL数据库01
    发表于 06-04 14:36

    如何使用原生hqc连接MySQL数据库

    springboot项目中使用原生hqc连接MySQL数据库
    发表于 06-08 12:12

    Mysql数据库的基本操作

    Mysql数据库入门-基本操作
    发表于 06-08 17:18

    c#如何连接mysql数据库

    (visual studio)c#连接mysql数据库
    发表于 06-13 20:56

    python如何连接MySql数据库

    Python入门(python连接MySql数据库)还能怎么记,大开眼界!
    发表于 06-14 07:48

    数据库连接问题

    请问一下各位,我想用字符串连接数据库MySQL数据库,这个里面的字符串是如何得来的?
    发表于 07-07 09:11

    源头开始呈现labview连接MYSQL数据库过程样本

    装的都是32位的,所有在MYSQL安装结束后,需要在mysql网站上下载并安装 mysql CONNETER/ODBC 32位 版本的数据库连接
    发表于 09-25 16:25

    ESP8266如何连接mysql数据库

    各位大神,我试图用ESP8266 连接mysql ,将温湿度传感器的数据,写入数据库mysql数据库
    发表于 01-12 09:22