# mm 数据查询语法指南

## 规则（Rules）

`db.new(表名, 主键)` 返回的数据管理器支持以下方法：

| 方法 | 用途 | 示例 |
|:----|:-----|:------|
| `get(条件, 排序, 字段)` | 查询列表 | `get({state:1}, "sort desc")` |
| `getObj(条件)` | 查询单条 | `getObj({id:1})` |
| `add(数据)` | 新增 | `add({title:"标题"})` |
| `set(条件, 数据)` | 修改 | `set({id:1}, {title:"新"})` |
| `del(条件)` | 删除 | `del({id:1})` |
| `count(条件)` | 计数 | `count({state:1})` |

## 方法（Methods）

### 步骤1：创建数据管理器

```javascript
var db_data = db.new('cms_article', 'article_id');
```

### 步骤2：构造查询条件

精确匹配直接传字段名和值，范围匹配加后缀：

| 后缀 | 含义 | 示例 |
|:----|:-----|:------|
| `_gt` | 大于 | `hot_gt: 100` |
| `_lt` | 小于 | `price_lt: 50` |
| `_gte` | 大于等于 | `score_gte: 60` |
| `_lte` | 小于等于 | `score_lte: 100` |
| `_min` | 范围下限 | `price_min: 10` |
| `_max` | 范围上限 | `price_max: 100` |
| `_like` | 模糊匹配 | `title_like: "关键词"` |
| `_has` | IN查询 | `id_has: [1,2,3]` |
| `_not` | 不等于 | `state_not: 0` |

### 步骤3：分页和排序

```javascript
db_data.size = 20;       // 每页20条
db_data.page = 1;        // 第1页
var list = await db_data.get({ state: 1 }, "sort desc, time desc");
var total = await db_data.count({ state: 1 });
```

### 步骤4：复杂查询

联表查询用 `this.sql.run()`：

```javascript
var result = await this.sql.run({
    table: "cms_article a",
    join: "LEFT JOIN cms_article_type t ON a.type_id = t.type_id",
    field: "a.*, t.name as type_name",
    where: { "a.state": 1 },
    orderby: "a.sort desc"
});
```

## 技巧（Tips）

- `db_data.size = 0` 不分页，返回所有匹配数据
- 排序格式：`"字段1 asc, 字段2 desc"`，不传则按默认排序
- `getObj` 只返回第一条数据，适合按主键查询
- `add` 返回新记录的主键值
