sqlx概览
开始之前,我们需要一些准备工作,包括:创建用于演示的数据库及数据、创建一个 Rust 项目以及为项目编写一些基础性代码。sqlx的查询构造器
本章将讨论 sqlx 的查询构造器。sqlx 提供了多种查询构造器:`query`、`query_as`、`query!`、`query_as!`、`QueryBuilder`等,合理使用将提升效率。这些查询构造器用来生成数据库所需要的 SQL 语句,不要被它们的名字迷惑了——认为它们是用来查询数据(SQL中的`SELECT`行为)sqlx查询数据
本章将讨论使用 sqlx 执行 `SELECT` 语句,对数据进行查询。sqlx实现增删改
本章将讨论使用 sqlx 进行增删改(`INSERT/DELETE/UPDATE`)操作。使用sqlx的事务实现转账
本章我们将通过用户之间转账来讨论 sqlx 的事务。为了保证转账的完整性、正确性,我们必须使用事务来处理。使用sqlx的QueryBuilder构建复杂、动态的查询
本章我们讨论如何优雅方便地使用 sqlx 构建复杂的、动态的 SQL。sqlx 提供了 [`QueryBuilder`](https://docs.rs/sqlx/latest/sqlx/struct.QueryBuilder.html) 结构体,它可以方便地实现 SQL 的构建。sqlx优雅地实现IN查询
在日常开发中,`IN` 查询是非常常见的需求,你会怎么来处理呢?借助 sqlx 的`QueryBuilder` 可以方便地实现。
sqlx优雅地实现IN查询
在日常开发中,IN 查询是非常常见的需求,你会怎么来处理呢?借助 sqlx 的QueryBuilder 可以方便地实现。
需求
SELECT * FROM member WHERE id IN(1,2,3,4);
有其它语言开发经验的人肯定想到:
- 将参数合并为字符串
 - 将合并后的字符串绑定到 sqlx 中
 
// 伪代码
let ids_str:Vec<String> = ids.iter().map(|id|id.to_string()).collect(); 
let ids_arg:String = ids_str.join(",");
let list:Vec<Member> = sqlx::query_as("SELECT * FROM member WHERE id IN(?)").bind(&ids_arg).fetch_all(conn).await.unwrap();
这种方式不会报错,甚至能工作的很好。但也可能遇到未知的BUG。
sqlx 的 QueryBuilder 提供了 push_tuples()方法,它能更优雅、可靠地实现这一需求。
pub async fn select_in(conn: &sqlx::MySqlPool, ids: &[u32]) -> Result<Vec<model::member::Member>> {
    let mut q = sqlx::QueryBuilder::new("SELECT * FROM member WHERE id IN");
    q.push_tuples(ids.iter(), |mut b, id| {
        b.push_bind(id);
    });
    let ms = q
        .build_query_as()
        .fetch_all(conn)
        .await
        .map_err(Error::from)?;
    Ok(ms)
}
