yang-db 0.1.2

个人使用数据库操作
Documentation
# select() 方法使用示例


本文档展示了 `yang-db` 库中 `select()` 方法的各种使用场景。

## 基本用法


### 查询所有记录


```rust
use yang_db::Database;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, sqlx::FromRow)]

struct User {
    id: i32,
    name: String,
    age: i32,
}

async fn example() -> Result<(), yang_db::DbError> {
    let db = Database::connect("mysql://root:password@localhost/test").await?;
    
    // 查询所有用户
    let users: Vec<User> = db.table("users")
        .select()
        .await?;
    
    println!("找到 {} 个用户", users.len());
    for user in users {
        println!("用户: {:?}", user);
    }
    
    Ok(())
}
```

### 使用 WHERE 条件查询


```rust
// 查询活跃用户
let active_users: Vec<User> = db.table("users")
    .where_and("status", "=", 1)
    .select()
    .await?;

// 查询年龄大于 18 的用户
let adult_users: Vec<User> = db.table("users")
    .where_and("age", ">", 18)
    .select()
    .await?;

// 使用多个条件
let filtered_users: Vec<User> = db.table("users")
    .where_and("status", "=", 1)
    .where_and("age", ">=", 18)
    .where_and("age", "<=", 65)
    .select()
    .await?;
```

## 高级用法


### 排序查询结果


```rust
// 按名称升序排序
let sorted_users: Vec<User> = db.table("users")
    .order("name", true)
    .select()
    .await?;

// 按年龄降序排序
let sorted_by_age: Vec<User> = db.table("users")
    .order("age", false)
    .select()
    .await?;

// 多字段排序
let multi_sorted: Vec<User> = db.table("users")
    .order("status", false)  // 先按状态降序
    .order("age", true)      // 再按年龄升序
    .select()
    .await?;
```

### 限制返回数量


```rust
// 获取前 10 条记录
let top_10: Vec<User> = db.table("users")
    .limit(10)
    .select()
    .await?;

// 分页查询:跳过前 20 条,获取接下来的 10 条
let page_2: Vec<User> = db.table("users")
    .limit(10)
    .offset(20)
    .select()
    .await?;
```

### 选择特定字段


```rust
#[derive(Debug, sqlx::FromRow)]

struct UserBasic {
    name: String,
    age: i32,
}

// 只查询 name 和 age 字段
let basic_info: Vec<UserBasic> = db.table("users")
    .field("name")
    .field("age")
    .select()
    .await?;
```

### 使用 IN 条件


```rust
// 查询特定 ID 的用户
let specific_users: Vec<User> = db.table("users")
    .where_in("id", vec![1, 2, 3, 5, 8])
    .select()
    .await?;

// 查询特定类别的产品
let categories = vec!["电子产品", "家具", "图书"];
let products: Vec<Product> = db.table("products")
    .where_in("category", categories)
    .select()
    .await?;
```

### 使用 BETWEEN 条件


```rust
// 查询年龄在 18-65 之间的用户
let working_age_users: Vec<User> = db.table("users")
    .where_between("age", 18, 65)
    .select()
    .await?;

// 查询价格在 100-1000 之间的产品
let mid_range_products: Vec<Product> = db.table("products")
    .where_between("price", 100.0, 1000.0)
    .select()
    .await?;
```

### 去重查询


```rust
#[derive(Debug, sqlx::FromRow)]

struct City {
    city: String,
}

// 查询所有不重复的城市
let cities: Vec<City> = db.table("users")
    .field("city")
    .distinct()
    .select()
    .await?;
```

## 处理空结果


`select()` 方法在没有匹配记录时返回空的 `Vec`,而不是错误:

```rust
let users: Vec<User> = db.table("users")
    .where_and("name", "=", "不存在的用户")
    .select()
    .await?;

if users.is_empty() {
    println!("没有找到匹配的用户");
} else {
    println!("找到 {} 个用户", users.len());
}
```

## 错误处理


```rust
match db.table("users").select::<User>().await {
    Ok(users) => {
        println!("查询成功,找到 {} 条记录", users.len());
        for user in users {
            println!("  - {:?}", user);
        }
    }
    Err(e) => {
        eprintln!("查询失败: {}", e);
    }
}
```

## select() vs find()


- `select()`: 返回 `Vec<T>`,可能包含多条记录或空列表
- `find()`: 返回 `Option<T>`,最多返回一条记录,自动添加 `LIMIT 1`

```rust
// 使用 find() 查询单条记录
let user: Option<User> = db.table("users")
    .where_and("id", "=", 1)
    .find()
    .await?;

// 使用 select() 查询多条记录
let users: Vec<User> = db.table("users")
    .where_and("status", "=", 1)
    .select()
    .await?;
```

## 性能提示


1. **使用字段选择**:只查询需要的字段可以减少数据传输量
2. **添加索引**:为常用的 WHERE 条件字段添加数据库索引
3. **使用 LIMIT**:对于大数据集,使用 LIMIT 限制返回数量
4. **避免 SELECT ***:明确指定需要的字段
5. **使用连接池**:Database 内部使用连接池,可以复用连接

## 完整示例


```rust
use yang_db::{Database, DbError};
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, sqlx::FromRow)]

struct User {
    id: i32,
    name: String,
    age: i32,
    email: String,
    status: i32,
}

#[tokio::main]

async fn main() -> Result<(), DbError> {
    // 连接数据库
    let db = Database::connect("mysql://root:password@localhost/test").await?;
    
    // 查询活跃用户,按年龄排序,限制 10 条
    let users: Vec<User> = db.table("users")
        .where_and("status", "=", 1)
        .where_and("age", ">=", 18)
        .order("age", true)
        .limit(10)
        .select()
        .await?;
    
    println!("找到 {} 个活跃成年用户:", users.len());
    for user in users {
        println!("  - {} ({}岁): {}", user.name, user.age, user.email);
    }
    
    Ok(())
}
```

## 注意事项


1. 确保结构体字段与数据库表字段匹配
2. 使用 `#[derive(sqlx::FromRow)]` 自动实现行映射
3. 对于可能为 NULL 的字段,使用 `Option<T>` 类型
4. 查询大量数据时考虑使用分页
5. 始终处理可能的错误情况