Skip to main content

dapper_style/
dapper_style.rs

1//! 演示 Dapper 风格的类型化 CRUD —— insert / query / update 全程无需手写 `SqlValue`。
2//!
3//! 运行方式:`cargo run --example dapper_style`
4//!
5//! 核心体验:
6//! - `Database::create(&mut user)` → 插入并回填自增主键(零 SqlValue)
7//! - `Query::new(...).query(&db).models::<User>()` → 条件查询自动映射回 `Vec<User>`
8//! - `Database::update(&mut user, &[("age", 30)])` → 直接执行并返回影响行数(零 SqlValue)
9//! - `Database::all::<User>()` / `first::<User>(id)` → 全表/按主键查询
10
11use torm::{Database, Model, Query};
12
13/// 用户模型:所有字段自动映射,无需手写 `columns()` / `from_row()`。
14#[derive(Debug, Clone, Model)]
15#[model(table_name = "users")]
16pub struct User {
17    pub id: i64,
18    pub name: String,
19    pub email: String,
20    pub age: i32,
21}
22
23impl User {
24    fn new(name: &str, email: &str, age: i32) -> Self {
25        Self {
26            id: 0, // 0 触发自增主键,insert 后自动回填
27            name: name.to_string(),
28            email: email.to_string(),
29            age,
30        }
31    }
32}
33
34#[tokio::main]
35async fn main() -> Result<(), Box<dyn std::error::Error>> {
36    let db = Database::sqlite(":memory:").await?;
37
38    // 自动建表(依据模型 schema)
39    db.auto_migrate::<User>().await?;
40    println!("表 users 已自动创建\n");
41
42    // === 1. insert:无需手写 SqlValue,主键自动自增并回填 ===
43    println!("=== 1. Insert (自增主键自动回填) ===");
44    let mut alice = User::new("Alice", "alice@example.com", 25);
45    db.create(&mut alice).await?;
46    let mut bob = User::new("Bob", "bob@example.com", 17);
47    db.create(&mut bob).await?;
48    let mut carol = User::new("Carol", "carol@example.com", 30);
49    db.create(&mut carol).await?;
50    println!(
51        "  id 自动分配: Alice={} Bob={} Carol={}\n",
52        alice.id, bob.id, carol.id
53    );
54
55    // === 2. query:条件查询自动映射回 Vec<User> ===
56    println!("=== 2. Query (自动映射回 User) ===");
57    let adults: Vec<User> = Query::new("users")
58        .where_gte("age", 18)
59        .order_by_desc("age")
60        .query(&db)
61        .models::<User>()
62        .await?;
63    for u in &adults {
64        println!("  id={} name={} email={} age={}", u.id, u.name, u.email, u.age);
65    }
66
67    // 分页 + 条件
68    let first_two: Vec<User> = Query::new("users")
69        .where_gt("age", 0)
70        .order_by_asc("id")
71        .limit(2)
72        .query(&db)
73        .models::<User>()
74        .await?;
75    println!("  前 2 条: {:?}", first_two.iter().map(|u| &u.name).collect::<Vec<_>>());
76    println!();
77
78    // === 3. update:直接执行 SQL,返回影响行数 ===
79    println!("=== 3. Update ===");
80    let affected = db.update(&mut alice, &[("age", 26)]).await?;
81    println!("  更新 age 影响 {} 行", affected);
82
83    // 多列同类型(全为 &str)可直接批量更新
84    db.update(
85        &mut alice,
86        &[("email", "alice_new@example.com"), ("name", "Alice A.")],
87    )
88    .await?;
89
90    // 重新查询验证
91    let refreshed: User = db.first::<User>(&alice.id.to_string()).await?.unwrap();
92    println!(
93        "  更新后: name={} age={} email={}\n",
94        refreshed.name, refreshed.age, refreshed.email
95    );
96
97    // === 4. 条件删除 ===
98    println!("=== 4. Delete ===");
99    let removed = db.delete(&mut bob).await?;
100    println!("  删除 Bob 影响 {} 行", removed);
101    let remaining = db.all::<User>().await?;
102    println!("  剩余 {} 条: {:?}", remaining.len(), remaining.iter().map(|u| &u.name).collect::<Vec<_>>());
103
104    println!("\n✅ insert / query / update / delete 全程零 SqlValue,Dapper 风格完成!");
105    Ok(())
106}