Ormer
Home
快速开始
GitHub
  • 简体中文
  • English
Home
快速开始
GitHub
  • 简体中文
  • English
  • Ormer 简介
  • 快速开始
  • 模型定义
  • 数据库连接
  • 数据操作
  • 查询构建器
  • 高级查询
  • 事务管理
  • 连接池

数据操作

本文档详细介绍 Ormer 的 CRUD (创建、读取、更新、删除) 操作。

插入数据 (Create)

单条插入

使用 insert() 方法插入单条记录:

#[derive(Debug, Model)]
#[table = "users"]
struct User {
    #[primary(auto)]
    id: i32,
    name: String,
    age: i32,
    email: Option<String>,
}

// 插入单条记录
db.insert(&User {
    id: 1,
    name: "Alice".to_string(),
    age: 25,
    email: Some("alice@example.com".to_string()),
}).await?;

批量插入

使用 Vec

let users = vec![
    User {
        id: 1,
        name: "Alice".to_string(),
        age: 25,
        email: None,
    },
    User {
        id: 2,
        name: "Bob".to_string(),
        age: 30,
        email: Some("bob@example.com".to_string()),
    },
    User {
        id: 3,
        name: "Charlie".to_string(),
        age: 35,
        email: Some("charlie@example.com".to_string()),
    },
];

db.insert(&users).await?;

使用数组

db.insert(&[
    User { id: 1, name: "Alice".to_string(), age: 25, email: None },
    User { id: 2, name: "Bob".to_string(), age: 30, email: None },
]).await?;

使用切片

let users = vec![/* ... */];
db.insert(&users[..]).await?;

插入或更新 (Upsert)

当遇到重复键时,自动更新现有记录:

// 首次插入
db.insert_or_update(&User {
    id: 1,
    name: "Alice".to_string(),
    age: 25,
    email: Some("alice@example.com".to_string()),
}).await?;

// 更新已存在的记录
db.insert_or_update(&User {
    id: 1,  // 相同的 ID
    name: "Alice Smith".to_string(),  // 更新名字
    age: 26,  // 更新年龄
    email: Some("alice.smith@example.com".to_string()),
}).await?;

批量插入或更新:

db.insert_or_update(&vec![
    User { id: 1, name: "Alice".to_string(), age: 25, email: None },
    User { id: 2, name: "Bob".to_string(), age: 30, email: None },
]).await?;

读取数据 (Read)

查询所有记录

let all_users: Vec<User> = db
    .select::<User>()
    .collect::<Vec<_>>()
    .await?;

条件查询

详见 查询构建器文档。

基本示例:

// 年龄大于等于 18 的用户
let adults: Vec<User> = db
    .select::<User>()
    .filter(|u| u.age.ge(18))
    .collect()
    .await?;

// 名字匹配
let alice: Vec<User> = db
    .select::<User>()
    .filter(|u| u.name.eq("Alice".to_string()))
    .collect()
    .await?;

排序和分页

// 按名字升序,取前 10 条
let users: Vec<User> = db
    .select::<User>()
    .order_by(|u| u.name.asc())
    .range(0..10)
    .collect()
    .await?;

// 按年龄降序,分页
let page2: Vec<User> = db
    .select::<User>()
    .order_by_desc(|u| u.age)
    .range(10..20)  // 第 2 页 (每页 10 条)
    .collect()
    .await?;

更新数据 (Update)

使用 update() 方法更新记录:

基本更新

let count = db
    .update::<User>()
    .filter(|u| u.age.ge(18))
    .set(|u| u.name, "Adult".to_string())
    .execute()
    .await?;

println!("Updated {} rows", count);

多字段更新

let count = db
    .update::<User>()
    .filter(|u| u.id.eq(1))
    .set(|u| u.name, "Alice Smith".to_string())
    .set(|u| u.age, 26)
    .set(|u| u.email, Some("alice.smith@example.com".to_string()))
    .execute()
    .await?;

条件更新

// 更新所有年龄小于 18 的用户
let count = db
    .update::<User>()
    .filter(|u| u.age.lt(18))
    .set(|u| u.name, "Minor".to_string())
    .execute()
    .await?;

删除数据 (Delete)

使用 delete() 方法删除记录:

条件删除

let count = db
    .delete::<User>()
    .filter(|u| u.age.lt(18))
    .execute()
    .await?;

println!("Deleted {} rows", count);

删除特定记录

let count = db
    .delete::<User>()
    .filter(|u| u.id.eq(1))
    .execute()
    .await?;

删除所有记录

⚠️ 警告: 这会删除表中的所有数据!

let count = db
    .delete::<User>()
    .execute()
    .await?;

表管理

创建表

db.create_table::<User>().await?;

这会生成 CREATE TABLE IF NOT EXISTS SQL 语句。

删除表

db.drop_table::<User>().await?;

生成 DROP TABLE IF EXISTS SQL 语句。

执行原生 SQL

查询并返回模型

let users: Vec<User> = db
    .exec_table::<User>("SELECT * FROM users WHERE age >= 18")
    .await?;

执行非查询 SQL

let affected_rows = db
    .exec_non_query("UPDATE users SET name = 'Test' WHERE id = 1")
    .await?;

println!("Affected {} rows", affected_rows);

完整示例

use ormer::{Database, DbType, Model};

#[derive(Debug, Model)]
#[table = "users"]
struct User {
    #[primary(auto)]
    id: i32,
    name: String,
    age: i32,
    email: Option<String>,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let db = Database::connect(DbType::Turso, "file:test.db").await?;
    db.create_table::<User>().await?;
    
    // 1. 插入数据
    db.insert(&User {
        id: 1,
        name: "Alice".to_string(),
        age: 25,
        email: Some("alice@example.com".to_string()),
    }).await?;
    
    db.insert(&vec![
        User { id: 2, name: "Bob".to_string(), age: 30, email: None },
        User { id: 3, name: "Charlie".to_string(), age: 35, email: None },
    ]).await?;
    
    // 2. 查询数据
    let all_users: Vec<User> = db.select::<User>().collect().await?;
    println!("All users: {:?}", all_users);
    
    // 3. 更新数据
    db.update::<User>()
        .filter(|u| u.id.eq(1))
        .set(|u| u.age, 26)
        .execute()
        .await?;
    
    // 4. 删除数据
    db.delete::<User>()
        .filter(|u| u.id.eq(3))
        .execute()
        .await?;
    
    // 5. 清理
    db.drop_table::<User>().await?;
    
    Ok(())
}

最佳实践

1. 批量操作优于循环

// ✅ 推荐: 批量插入
db.insert(&users).await?;

// ❌ 避免: 循环插入
for user in &users {
    db.insert(user).await?;  // 慢!
}

2. 使用事务保证一致性

let mut txn = db.begin().await?;

txn.insert(&user1).await?;
txn.insert(&user2).await?;

txn.commit().await?;

3. 合理设置过滤条件

// ✅ 明确指定条件
db.delete::<User>()
    .filter(|u| u.id.eq(1))
    .execute()
    .await?;

// ❌ 危险: 忘记过滤条件
db.delete::<User>().execute().await?;  // 删除所有!

4. 检查操作结果

let count = db.update::<User>()
    .filter(|u| u.id.eq(1))
    .set(|u| u.name, "New Name".to_string())
    .execute()
    .await?;

if count == 0 {
    println!("No rows updated");
}
Prev
数据库连接
Next
查询构建器