Rust语言从入门到精通系列 - SQLx模块MySQL入门

1401 字
7 分钟
Rust语言从入门到精通系列 - SQLx模块MySQL入门

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<(), Box<dyn std::error::Error>> {
dotenv::dotenv().ok();
let pool = MySqlPoolOptions::new()
.max_connections(5)
.connect(&dotenv::var("DATABASE_URL")?)
.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::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?;
let mut conn = pool.acquire().await?;
let pool = MySqlPoolOptions::new()
.max_connections(5)
.connect("mysql://username:password@hostname:port/database")
.await?;
let mut conn = pool.acquire().await?;
// ...
Ok(())
}

总结#

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

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
Rust语言从入门到精通系列 - SQLx模块MySQL入门
https://tinyzzh.github.io/posts/2023-05-30-rust_sqlx_001_basic_mysql/
作者
TinyZ Zzh
发布于
2023-05-30
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
TinyZ Zzh
专注于高并发服务器、网络游戏相关(Java、PHP、Unity3D、Unreal Engine等)技术,热爱游戏事业, 正在努力实现自我价值当中。
公告
欢迎来到我的博客!这是一则示例公告。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
211
分类
38
标签
200
总字数
337,853
运行时长
0
最后活动
0 天前

文章目录