Github: https://github.com/launchbadge/sqlx
Doc: https://docs.rs/crate/sqlx/0.4.0
Rust sqlx 0.4.0 最近正式发布了,上次用的它的 0.4 beta 版本,因为 0.3.x 版本在 MySQL 5.x 下有诡异 BUG,官方让尝试 beta 版(master) 能正常工作。然而 0.4.0 正式版文档还是有些坑(提交问题后,刚看了下官方已经修正了,速度很快!),花了一下午时间把坑填了,搞一个无错版本的 example 出来了。
这个版本如果用 tokio 会提示 cc 版本不兼容。必须用 async-std,继续等官方完善。
sqlx 默认就是异步,如果你非要同步,那么得 block_on() 阻塞一下,也还算方便,得益于 Rust 的 Future 机制,性能损失应该很小,你都用同步了,这点损失应该忽略不计了,当然如果用纯异步那效率肯定高了。
Cargo.toml
[package]
name = "xxx"
version = "0.1.0"
authors = ["xx <xx@xx.xx>"]
edition = "2018"
[dependencies]
#sqlx = { git = "https://github.com/launchbadge/sqlx", branch = "master", default-features = false, features = [ "runtime-tokio", "macros", "mysql"] }
sqlx = { version="0.4.1", default-features = false, features = ["macros", "mysql", "runtime-async-std-native-tls"] }
#tokio = { version = "0.2", feature="all" }
async-std = { version="1.7.0", fetures = ["attributes"] }
futures="0.3.8"
Code:
use futures::TryStreamExt;
use async_std::task::block_on;
use sqlx::Row;
const DATABASE_URL: &str = "mysql://root:passwd@localhost:3306/test";
#[derive(sqlx::FromRow, Debug)]
struct User {
gid: u64,
uid: u64,
}
// 为了方便查看错误,我直接 unwrap() 了,实际使用的时候,改为 ? ,然后在上层判断!
async fn fn1() -> Result<(), sqlx::Error> {
let pool = sqlx::MySqlPool::connect(DATABASE_URL).await.unwrap();
// one tuple
let row: (i32, ) = sqlx::query_as("SELECT ?").bind(123i32).fetch_one(&pool).await.unwrap();
dbg!(row.0);
// one row
let row = sqlx::query_as::<_, User>("SELECT * FROM tablename LIMIT 1").fetch_one(&pool).await.unwrap();
dbg!(row);
// Vec + try_get()
let mut rows = sqlx::query("SELECT gid, uid FROM tablename LIMIT 10").fetch_all(&pool).await.unwrap();
for row in rows {
let gid:i32 = row.try_get("gid")?; // use sqlx::Row
dbg!(row);
}
// Vec + Struct
let mut rows = sqlx::query_as::<_, User>("SELECT gid, uid FROM tablename LIMIT 10").fetch_all(&pool).await.unwrap();
for row in rows {
dbg!(row);
}
// Streeam + try_get()
// use futures::TryStreamExt;
let mut rows = sqlx::query("SELECT * FROM tablename LIMIT 10").fetch(&pool);
while let Some(row) = rows.try_next().await.unwrap() {
let gid:i32 = row.try_get("gid")?; // use sqlx::Row;
dbg!(row);
}
// Streeam + Struct
let mut rows = sqlx::query_as::<_, User>("SELECT * FROM tablename LIMIT 10").fetch(&pool);
while let Some(row) = rows.try_next().await.unwrap() {
dbg!(row);
}
// execute
//sqlx::query("DELETE FROM tablename").execute(&mut conn).await?;
sqlx::query("DELETE FROM tablename WHERE 1=2").execute(&pool).await?;
// Advanced! Not recommended! IDE not supportted! need export var in shell!
// 高级特性,依赖编译器推断,不推荐使用!IDE 不支持,并且需要在 Shell 下执行下面的命令。
// export DATABASE_URL="mysql://root@localhost:3306/test"
//let rows = sqlx::query_as!(User, "SELECT gid, uid FROM tablename WHERE 1=?", 1).fetch_all(&pool).await.unwrap();
//dbg!(rows);
Ok(())
}
fn main() {
//futures::executor::block_on(fn1());
block_on(fn1());
}