11.1.1.2. 数据插入和查询

rusqlite-badge cat-database-badge

Connection::open 将打开在前一章节实例中创建的数据库 cats 的连接。下面的实例使用 Connectionexecute 方法将数据插入 cat_colorscats 两张表中。首先,将数据插入到 cat_colors 表中。随后,使用 Connectionlast_insert_rowid 方法来获取 cat_colors 表最后插入记录的 id。当向 cats 表中插入数据时,使用此 id。然后,使用 prepare 方法准备执行 select 查询操作,该方法提供 statement 结构体。最后,使用 statementquery_map 方法执行查询。

use rusqlite::NO_PARAMS;
use rusqlite::{Connection, Result};
use std::collections::HashMap;

#[derive(Debug)]
struct Cat {
    name: String,
    color: String,
}

fn main() -> Result<()> {
    let conn = Connection::open("cats.db")?;

    let mut cat_colors = HashMap::new();
    cat_colors.insert(String::from("Blue"), vec!["Tigger", "Sammy"]);
    cat_colors.insert(String::from("Black"), vec!["Oreo", "Biscuit"]);

    for (color, catnames) in &cat_colors {
        conn.execute(
            "INSERT INTO cat_colors (name) values (?1)",
            &[&color.to_string()],
        )?;
        let last_id: String = conn.last_insert_rowid().to_string();

        for cat in catnames {
            conn.execute(
                "INSERT INTO cats (name, color_id) values (?1, ?2)",
                &[&cat.to_string(), &last_id],
            )?;
        }
    }
    let mut stmt = conn.prepare(
        "SELECT c.name, cc.name from cats c
         INNER JOIN cat_colors cc
         ON cc.id = c.color_id;",
    )?;

    let cats = stmt.query_map(NO_PARAMS, |row| {
        Ok(Cat {
            name: row.get(0)?,
            color: row.get(1)?,
        })
    })?;

    for cat in cats {
        println!("Found cat {:?}", cat);
    }

    Ok(())
}