Rust - mysql 新的选择

一、添加mysql依赖

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,是因为这些宏的使用,需要在编译器连接到数据库才行

二、设置database_url,创建连接池

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?;
三、查询sql结果

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);
四、查询sql结果集转化成struct

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?;

你可能感兴趣的:(Rust)