sqlx 是同时支持tokio2.0和async-std的异步mysql
[dependencies]
tokio = {version = "0.2.15", features = ["full"] }
sqlx = {version = "0.3", default-features = false, features = ["runtime-tokio", "mysql", "chrono"]}
PS: 为什么不添加macro的feature,是因为这些宏的使用,需要在编译器连接到数据库才行
DSN:mysql://root:[email protected]:3306/testdb
支持的连接池的参数如下:
pub max_size: u32, // 连接池的上限
pub connect_timeout: Duration, // 连接超时时间
pub min_size: u32, // 连接池的下限
pub max_lifetime: Option, // 所有连接的最大生命周期
pub idle_timeout: Option, // 空闲连接的生命周期
创建连接池:
let pool = sqlx::MySqlPool::builder().
max_size(100).
min_size(10).
connect_timeout(std::time::Duration::from_secs(10)).
max_lifetime(std::time::Duration::from_secs(1800)).
idle_timeout(std::time::Duration::from_secs(600)).
build(&std::env::var("DATABASE_URL").unwrap()).await?;
1、使用fetch,获取cursor游标,自己处理row
let sql = "select id, username from t_user where id < ?";
let mut cursor = sqlx::query(sql).bind(3).fetch(&pool);
while let Some(row) = cursor.next().await? {
let user = User {
id: row.get("id"),
username: row.get("username"),
};
println!("{:?}", user);
}
2、使用fetch,加map,自动处理row
#[derive(Debug)]
struct User {
id: u32,
username: String,
}
// -------------------
let sql = "select id, username from t_user limit 10";
let stream = sqlx::query(sql)
.map(|row: sqlx::mysql::MySqlRow| User {
id: row.try_get("id").unwrap_or(0),
username: row.try_get("username").unwrap_or("".into()),
})
.fetch(&pool);
tokio::pin!(stream);
while let Some(user) = stream.try_next().await? {
println!("{:?}", user);
}
3、使用execute,执行更新操作,返回affect_rows
let sql = r#"update t_user set username = ? where id > ?"#;
let mut affect_rows = sqlx::query(sql).bind("wy").bind(1).execute(&pool).await?;
println!("{:?}", affect_rows);
4、使用execute和fetch,执行插入操作,获取自增id
let mut conn = pool.acquire().await?;
let sql = r#"insert into t_user (username, password) value (?, ?);"#;
let affect_rows = sqlx::query(sql).bind("wy").bind("123456").execute(&mut conn).await?;
println!("{:?}", affect_rows);
let sql = r#"select last_insert_id();"#;
// use tokio::stream::StreamExt;
let insert_id: u64 = sqlx::query(sql).fetch(&mut conn).next().await?.unwrap().get(0);
println!("{:?}", insert_id);
drop(conn);
1、定义一个查询的struct
#[derive(Debug)]
struct User {
id: i32,
username: String,
}
impl<'c> sqlx::FromRow<'c, MySqlRow<'c>> for User {
fn from_row(row: &MySqlRow<'c>) -> Result {
Ok(User {
id: row.get("id"),
username: row.get("username"),
})
}
}
2、使用fetch
获取结果集Vec
的流Stream
数据
let sql = "select id, username from t_user where id < ?";
// use tokio::stream::StreamExt;
let mut stream = sqlx::query_as::<_, User>(sql).bind(3).fetch(&pool);
while let Some(user) = stream.try_next().await? {
println!("{:?}", user);
}
3、使用fetch_one
获取一条结果集User
let sql = "select id, username from t_user where id < ?";
let user: User = sqlx::query_as::<_, User>(sql).bind(3).fetch_one(&pool).await?;
println!("{:?}", user);
4、使用fetch_all
获取所有的结果集Vec
let sql = "select id, username from t_user where id < ?";
let users: Vec = sqlx::query_as::<_, User>(sql).bind(3).fetch_all(&pool).await?;
println!("{:?}", users);
let mut conn = pool.begin().await?;
let sql = r#"insert into t_user (username, password) value (?, ?)"#;
sqlx::query(sql).bind("wy").bind("123456").execute(&mut conn).await?;
conn.commit().await?;