# ThinkORM 使用指南

<cite>
**本文引用的文件**
- [composer.json](file://composer.json)
- [composer.lock](file://composer.lock)
- [common.php](file://vendor/thinkcmf/cmf/src/common.php)
- [OptionModel.php](file://vendor/thinkcmf/cmf/src/model/OptionModel.php)
- [UserModel.php](file://vendor/thinkcmf/cmf/src/model/UserModel.php)
- [AdminBaseController.php](file://vendor/thinkcmf/cmf/src/controller/AdminBaseController.php)
- [AppController.php](file://vendor/thinkcmf/cmf-api/src/admin/controller/AppController.php)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本指南围绕 ThinkCMF 项目中 ThinkORM 的使用进行系统性梳理，覆盖模型创建、数据读写与查询构建、模型关系、查询构造器、数据验证与过滤、批量操作与事务、性能优化以及常见场景实践。文档以仓库中实际存在的 ThinkCMF 包为依据，结合控制器与模型示例，帮助读者快速掌握 ThinkORM 在 ThinkCMF 中的典型用法。

## 项目结构
- ThinkCMF 通过 Composer 管理依赖，核心 ORM 能力来自 ThinkPHP 8.x 框架（在 ThinkCMF 8.0.x 版本中引入）。
- 项目中与 ORM 直接相关的代码主要集中在以下位置：
  - ThinkCMF 核心包：vendor/thinkcmf/cmf/src
  - ThinkCMF API 包：vendor/thinkcmf/cmf-api/src
  - ThinkCMF 应用包：vendor/thinkcmf/cmf-app/src
- 本指南聚焦 vendor 目录下的 ThinkCMF 包，结合控制器与模型示例，展示 ThinkORM 的实际使用方式。

```mermaid
graph TB
A["应用入口<br/>public/index.php"] --> B["框架引导<br/>vendor/thinkcmf/cmf/src"]
B --> C["控制器<br/>vendor/thinkcmf/cmf/src/controller/*.php"]
C --> D["模型<br/>vendor/thinkcmf/cmf/src/model/*.php"]
D --> E["数据库查询<br/>think\db\Query"]
E --> F["数据库实例"]
```

**图表来源**
- [composer.json:30-42](file://composer.json#L30-L42)
- [composer.lock:504-564](file://composer.lock#L504-L564)

**章节来源**
- [composer.json:30-42](file://composer.json#L30-L42)
- [composer.lock:504-564](file://composer.lock#L504-L564)

## 核心组件
- 模型基类与命名空间
  - ThinkORM 模型位于 cmf\model 命名空间下，继承自 think\Model。
  - 示例模型：OptionModel、UserModel。
- 控制器中的查询使用
  - 控制器通过模型类进行条件查询、字段值获取、单条记录查找等。
- 查询构造器
  - 通过 Db::name 或模型静态方法配合 where、find、select、value 等实现查询。

关键点
- 模型类通常显式设置表名与字段类型，便于 ORM 映射与序列化。
- 控制器中多处使用 where 条件、find 单条查询、value 字段取值、destroy 删除等。

**章节来源**
- [OptionModel.php:15-32](file://vendor/thinkcmf/cmf/src/model/OptionModel.php#L15-L32)
- [UserModel.php:15-44](file://vendor/thinkcmf/cmf/src/model/UserModel.php#L15-L44)
- [AdminBaseController.php:42-42](file://vendor/thinkcmf/cmf/src/controller/AdminBaseController.php#L42-L42)
- [AppController.php:197-197](file://vendor/thinkcmf/cmf-api/src/admin/controller/AppController.php#L197-L197)

## 架构总览
ThinkORM 在 ThinkCMF 中的使用遵循“控制器-模型-查询构造器”的分层结构：
- 控制器负责业务流程与参数处理；
- 模型负责表映射与字段类型声明；
- 查询构造器负责 SQL 组装与执行。

```mermaid
classDiagram
class BaseModel {
"+name : string"
"+autoWriteTimestamp : bool|string"
"+updateTime : bool|string"
"+type : array"
}
class OptionModel {
"+name = 'option'"
"+type.option_value = 'array'"
}
class UserModel {
"+name = 'user'"
"+autoWriteTimestamp = true"
"+updateTime = false"
"+type.more = 'array'"
}
class AdminBaseController {
"+initialize()"
"+_initializeView()"
}
class AppController {
"+某方法()"
}
BaseModel <|-- OptionModel
BaseModel <|-- UserModel
AdminBaseController --> UserModel : "查询用户"
AppController --> UserModel : "校验密码"
```

**图表来源**
- [OptionModel.php:15-32](file://vendor/thinkcmf/cmf/src/model/OptionModel.php#L15-L32)
- [UserModel.php:15-44](file://vendor/thinkcmf/cmf/src/model/UserModel.php#L15-L44)
- [AdminBaseController.php:42-42](file://vendor/thinkcmf/cmf/src/controller/AdminBaseController.php#L42-L42)
- [AppController.php:197-197](file://vendor/thinkcmf/cmf-api/src/admin/controller/AppController.php#L197-L197)

## 详细组件分析

### 模型与数据读写
- 表映射与字段类型
  - OptionModel 显式设置表名为 option，并将 option_value 字段类型声明为 array，便于 JSON 存储与解析。
  - UserModel 显式设置表名为 user，启用自动写入时间戳，关闭更新时间戳字段，将 more 字段声明为 array。
- 常见读写操作
  - 查找单条记录：UserModel::where('id', $id)->find()
  - 获取单个字段值：UserModel::where('id', 1)->value('user_pass')
  - 创建与更新：OptionModel::create(...)、OptionModel::where(...)->update(...)
  - 删除：LinkModel::destroy($id)（示例中出现）

```mermaid
sequenceDiagram
participant C as "控制器"
participant M as "UserModel"
participant Q as "查询构造器"
participant DB as "数据库"
C->>M : "where('id', 1)"
M->>Q : "构建查询"
Q->>DB : "执行查询"
DB-->>Q : "返回结果集"
Q-->>M : "返回记录"
M-->>C : "find() 返回单条记录"
```

**图表来源**
- [AdminBaseController.php:42-42](file://vendor/thinkcmf/cmf/src/controller/AdminBaseController.php#L42-L42)
- [AppController.php:197-197](file://vendor/thinkcmf/cmf-api/src/admin/controller/AppController.php#L197-L197)

**章节来源**
- [OptionModel.php:15-32](file://vendor/thinkcmf/cmf/src/model/OptionModel.php#L15-L32)
- [UserModel.php:15-44](file://vendor/thinkcmf/cmf/src/model/UserModel.php#L15-L44)
- [AdminBaseController.php:42-42](file://vendor/thinkcmf/cmf/src/controller/AdminBaseController.php#L42-L42)
- [AppController.php:197-197](file://vendor/thinkcmf/cmf-api/src/admin/controller/AppController.php#L197-L197)

### 查询构造器与条件查询
- 条件查询
  - where('id', $id)、where('option_name', $key)、where('id', 'in', $ids) 等。
- 字段选择与取值
  - field('id')、value('user_pass')、column('role_id') 等。
- 排序与集合
  - order([...])->select()、按需排序与批量获取。
- 连接查询
  - alias('a') 与多表关联查询（示例中出现）。
- 子查询
  - where(function ($query) use (...) {...}) 支持闭包子查询条件。

```mermaid
flowchart TD
Start(["开始"]) --> Build["构建查询条件<br/>where/alias/order"]
Build --> Exec{"执行查询"}
Exec --> |单条| Find["find()"]
Exec --> |多条| Select["select()"]
Exec --> |字段值| Value["value('field')"]
Exec --> |列数组| Column["column('col')"]
Exec --> |删除| Destroy["destroy(ids)"]
Find --> End(["结束"])
Select --> End
Value --> End
Column --> End
Destroy --> End
```

**图表来源**
- [AdminBaseController.php:42-42](file://vendor/thinkcmf/cmf/src/controller/AdminBaseController.php#L42-L42)
- [AppController.php:197-197](file://vendor/thinkcmf/cmf-api/src/admin/controller/AppController.php#L197-L197)
- [common.php:540-556](file://vendor/thinkcmf/cmf/src/common.php#L540-L556)

**章节来源**
- [AdminBaseController.php:42-42](file://vendor/thinkcmf/cmf/src/controller/AdminBaseController.php#L42-L42)
- [AppController.php:197-197](file://vendor/thinkcmf/cmf-api/src/admin/controller/AppController.php#L197-L197)
- [common.php:540-556](file://vendor/thinkcmf/cmf/src/common.php#L540-L556)

### 模型关系定义
- ThinkCMF 仓库中未发现显式的 hasOne、hasMany、belongsTo、belongsToMany 关系定义示例。
- 常见做法是在模型中通过关联方法定义关系，例如：
  - belongsTo('ParentModel', 'parent_id', 'id')
  - hasMany('ChildModel', 'parent_id', 'id')
  - belongsToMany('OtherModel', 'pivot_table', 'self_key', 'other_key')
- 若需实现复杂关系，建议在具体业务模型中补充关联方法，并在控制器或服务层按需加载。

[本节为概念性说明，未直接分析具体文件，故无“章节来源”]

### 数据验证与过滤
- 字段验证规则
  - ThinkORM 本身不内置字段级验证规则；建议在控制器或服务层对输入参数进行校验（如范围、格式、必填等），再写入模型。
- 数据清洗
  - 对输入参数进行 trim、过滤、转义等处理，避免注入与脏数据进入数据库。
- 密码比较
  - ThinkCMF 提供 cmf_compare_password 方法用于安全比对，避免明文密码存储。

**章节来源**
- [common.php:314-321](file://vendor/thinkcmf/cmf/src/common.php#L314-L321)

### 批量操作与事务
- 批量插入/更新/删除
  - 使用 create([...])、saveAll([...])、update([...])、destroy([...]) 等方法实现批量操作。
- 事务处理
  - 使用 Db::transaction(...) 包裹多步写操作，确保原子性与一致性。
- 注意事项
  - 大批量数据建议分批处理，避免内存与超时问题。

[本节为概念性说明，未直接分析具体文件，故无“章节来源”]

### 性能优化
- 延迟加载与预加载
  - 关系查询时优先使用 with 预加载，减少 N+1 查询。
- 查询优化
  - 合理使用索引字段作为 where 条件，避免全表扫描。
  - 使用 field 精确选择字段，减少不必要的数据传输。
- 缓存
  - 对热点数据使用缓存（如 cache(...)），降低数据库压力。
- 分页与排序
  - 使用 limit/offset 或 paginate 实现分页，避免一次性加载大量数据。

[本节为概念性说明，未直接分析具体文件，故无“章节来源”]

## 依赖分析
- ThinkCMF 8.0.x 依赖 ThinkPHP 8.x 框架，ORM 能力由框架提供。
- 通过 composer.json 与 composer.lock 可确认核心包版本与依赖关系。

```mermaid
graph TB
Root["ThinkCMF 根项目"] --> CMF["thinkcmf/cmf"]
Root --> API["thinkcmf/cmf-api"]
Root --> APP["thinkcmf/cmf-app"]
CMF --> FW["topthink/framework (~8.1.0)"]
```

**图表来源**
- [composer.json:30-42](file://composer.json#L30-L42)
- [composer.lock:504-564](file://composer.lock#L504-L564)

**章节来源**
- [composer.json:30-42](file://composer.json#L30-L42)
- [composer.lock:504-564](file://composer.lock#L504-L564)

## 性能考虑
- 避免 N+1 查询：使用 with 预加载关联数据。
- 精准查询：仅选择必要字段，合理使用索引字段作为条件。
- 批处理：大批量写入采用分批提交，结合事务保证一致性。
- 缓存策略：热点配置与常量数据使用缓存，减少数据库访问。

[本节为通用指导，未直接分析具体文件，故无“章节来源”]

## 故障排查指南
- 常见问题
  - 权限校验失败：检查 Header 中 token 与 session 的匹配逻辑。
  - 密码校验失败：确认密码比较函数与数据库中存储格式一致。
  - 查询无结果：核对 where 条件与字段类型，确保 id/主键正确。
- 定位手段
  - 在控制器中打印查询 SQL 与参数，结合数据库日志定位问题。
  - 对批量操作增加 try/catch 并记录异常，便于回滚与重试。

**章节来源**
- [AdminBaseController.php:34-40](file://vendor/thinkcmf/cmf/src/controller/AdminBaseController.php#L34-L40)
- [AppController.php:196-200](file://vendor/thinkcmf/cmf-api/src/admin/controller/AppController.php#L196-L200)

## 结论
ThinkCMF 在 ThinkORM 的使用上体现了清晰的分层与简洁的查询模式：控制器负责业务流程，模型负责表映射与字段类型，查询构造器承担 SQL 组装与执行。结合事务、缓存与分批处理等策略，可有效提升系统性能与稳定性。对于关系定义与字段验证等高级能力，建议在具体业务模型与服务层中按需扩展。

[本节为总结性内容，未直接分析具体文件，故无“章节来源”]

## 附录
- 快速参考
  - 单条查询：Model::where(...)->find()
  - 多条查询：Model::order([...])->select()
  - 字段值：Model::where(...)->value('field')
  - 删除：Model::destroy($id)
  - 创建：Model::create([...])
  - 更新：Model::where(...)->update([...])

[本节为通用指导，未直接分析具体文件，故无“章节来源”]