tachybase_todo/docs/zh-CN/api/database/repository.md
Junyi 796e73ae5a
refactor(doc): change to new structure (#804)
* refactor(doc): change to new structure

* docs: add database docs

* docs: add collection docs

* docs: add db field examples

* docs(api): fix filename and menu path

* docs: add database docs

* docs: add db operators doc

* docs: add resourcer menu

* docs: add resourcer docs

* docs: fix api docs

* docs: refactor api menu structure

* feat: update docs (#830)

* feat: updates

* feat: update docs

* chore: ignore docs from ci

Co-authored-by: Junyi <mytharcher@users.noreply.github.com>
Co-authored-by: mytharcher <mytharcher@gmail.com>

* docs: add database methods docs

* docs: add missed api

* docs: fix api docs

* feat: update development docs (#833)

* feat: update development docs

* feat: update docs

* feat: update docs

* docs: add first plugin example (#834)

* feat: update docs

* feat: update docs

* docs: fix typo

Co-authored-by: chenos <chenlinxh@gmail.com>
2022-09-19 09:23:01 +08:00

356 lines
9.7 KiB
Markdown

# Repository
数据表数据仓库管理类。大部分基于数据表的数据存取等操作均通过该类实现。
## 构造函数
通常不会直接由开发者调用,主要通过 `db.registerRepositories()` 注册类型以后,在 `db.colletion()` 的参数中指定对应已注册的仓库类型,并完成实例化。
**签名**
* `constructor(collection: Collection)`
**示例**
```ts
import { Repository } from '@nocobase/database';
class MyRepository extends Repository {
async myQuery(sql) {
return this.database.sequelize.query(sql);
}
}
db.registerRepositories({
books: MyRepository
});
db.collection({
name: 'books',
// here link to the registered repository
repository: 'books'
});
await db.sync();
const books = db.getRepository('books') as MyRepository;
await books.myQuery('SELECT * FROM books;');
```
## 实例成员
### `database`
上下文所在的数据库管理实例。
### `collection`
对应的数据表管理实例。
### `model`
对应的数据模型类。
## 实例方法
### `count()`
从数据库查询特定条件的数据总数。相当于 Sequelize 中的 `Model.count()`
**签名**
* `count(options?: CountOptions): Promise<number>`
**参数**
| 参数名 | 类型 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `options.filter?` | `Filter` | `{}` | 查询条件 |
| `options.fields?` | `string[]` | - | 计数列 |
| `options.transaction?` | `Transaction` | - | 事务 |
`filter` 为兼容 Sequelize 查询条件的扩展形式,更多操作符支持详见 [Operators](./operators.md)。
**示例**
```ts
const books = db.getRepository('books');
const count = await books.count({
filter: {
title: '三字经'
}
});
```
### `find()`
从数据库查询特定条件的数据集。相当于 Sequelize 中的 `Model.findAll()`
**签名**
* `async find(options?: FindOptions): Promise<Model[]>`
**参数**
| 参数名 | 类型 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `options.filterByTk?` | `number \| string` | `{}` | 主键值 |
| `options.filter?` | `Filter` | `{}` | 查询条件 |
| `options.fields?` | `string[]` | - | 查询列 |
| `options.appends?` | `string[]` | - | 追加关系数据列 |
| `options.except?` | `string[]` | - | 排除数据列 |
| `options.sort?` | `string[] \| string` | - | 排序 |
| `options.limit?` | `number` | - | 限制条数 |
| `options.offset?` | `number` | - | 跳过条数 |
| `options.transaction?` | `Transaction` | - | 事务 |
`fields``except` 通常只使用其一,相当于 Sequelize 中 `attributes``include` / `exclude`。`appends` 通常用于关系字段。
**示例**
```ts
const posts = db.getRepository('posts');
const results = await posts.find({
filter: {
createdAt: {
$gt: '2022-01-01T00:00:00.000Z',
}
},
fields: ['title'],
appends: ['user'],
});
```
### `findOne()`
从数据库查询特定条件的单条数据。相当于 Sequelize 中的 `Model.findOne()`
**签名**
* `async findOne(options?: FindOneOptions): Promise<Model | null>`
**参数**
| 参数名 | 类型 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `options.filterByTk?` | `number \| string` | `{}` | 主键值 |
| `options.filter?` | `Filter` | `{}` | 查询条件 |
| `options.fields?` | `string[]` | - | 查询列 |
| `options.appends?` | `string[]` | - | 追加关系数据列 |
| `options.except?` | `string[]` | - | 排除数据列 |
| `options.sort?` | `string[] \| string` | - | 排序 |
| `options.offset?` | `number` | - | 跳过条数 |
| `options.transaction?` | `Transaction` | - | 事务 |
大部分参数与 `find()` 相同,不同之处在于 `findOne()` 只返回单条数据,所以不需要 `limit` 参数,且查询时始终为 `1`
**示例**
```ts
const posts = db.getRepository('posts');
const result = await posts.findOne({
filterByTk: 1,
});
```
### `findAndCount()`
从数据库查询特定条件的数据集和总数。相当于 Sequelize 中的 `Model.findAndCountAll()`
**签名**
* `async findAndCount(options?: FindAndCountOptions): Promise<[Model[], number]>`
**参数**
所有参数与 [`find()`](#find) 相同。
### `create()`
向数据表插入一条新创建的数据。相当于 Sequelize 中的 `Model.create()`。当要创建的数据对象携带关系字段的信息时,会一并创建或更新相应的关系数据记录。
**签名**
* `async create<M extends Model>(options: CreateOptions): Promise<M>`
**参数**
| 参数名 | 类型 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `options.values` | `M` | `{}` | 插入的数据对象 |
| `options.whitelist?` | `string[]` | - | `values` 字段的白名单,只有名单内的字段会被存储 |
| `options.blacklist?` | `string[]` | - | `values` 字段的黑名单,名单内的字段不会被存储 |
| `options.transaction?` | `Transaction` | - | 事务 |
如果没有传入事务参数,该方法会自动创建一个内部事务。
**示例**
```ts
const posts = db.getRepository('posts');
const result = await posts.create({
values: {
title: 'NocoBase 1.0 发布日志',
tags: [
// 有关系表主键值时为更新该条数据
{ id: 1 },
// 没有主键值时为创建新数据
{ name: 'NocoBase' },
]
},
});
```
### `createMany()`
向数据表插入多条新创建的数据。相当于多次调用 `create()` 方法。
**签名**
* `createMany(options: CreateManyOptions): Promise<Model[]>`
**参数**
| 参数名 | 类型 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `options.records` | `Model[]` | - | 插入的数据对象数组 |
| `options.whitelist?` | `string[]` | - | `values` 字段的白名单,只有名单内的字段会被存储 |
| `options.blacklist?` | `string[]` | - | `values` 字段的黑名单,名单内的字段不会被存储 |
| `options.transaction?` | `Transaction` | - | 事务 |
如果没有传入事务参数,该方法会自动创建一个内部事务。
**示例**
```ts
const posts = db.getRepository('posts');
const results = await posts.createMany({
records: [
{
title: 'NocoBase 1.0 发布日志',
tags: [
// 有关系表主键值时为更新该条数据
{ id: 1 },
// 没有主键值时为创建新数据
{ name: 'NocoBase' },
]
},
{
title: 'NocoBase 1.1 发布日志',
tags: [
{ id: 1 }
]
},
],
});
```
### `update()`
更新数据表中的数据。相当于 Sequelize 中的 `Model.update()`。当要更新的数据对象携带关系字段的信息时,会一并创建或更新相应的关系数据记录。
**签名**
* `async update<M extends Model>(options: UpdateOptions): Promise<M>`
**参数**
| 参数名 | 类型 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `options.filterByTk` | `number \| string` | - | 查询主键 |
| `options.filter` | `Filter` | - | 查询条件 |
| `options.values` | `M` | `{}` | 更新的数据对象 |
| `options.whitelist?` | `string[]` | - | `values` 字段的白名单,只有名单内的字段会被存储 |
| `options.blacklist?` | `string[]` | - | `values` 字段的黑名单,名单内的字段不会被存储 |
| `options.transaction?` | `Transaction` | - | 事务 |
`filterByTk``filter` 至少要传其一。如果没有传入事务参数,该方法会自动创建一个内部事务。
**示例**
```ts
const posts = db.getRepository('posts');
const result = await posts.update({
filterByTk: 1,
values: {
title: 'NocoBase 1.0 发布日志',
tags: [
// 有关系表主键值时为更新该条数据
{ id: 1 },
// 没有主键值时为创建新数据
{ name: 'NocoBase' },
]
},
});
```
### `destory()`
删除数据表中的数据。相当于 Sequelize 中的 `Model.destroy()`
**签名**
* `async destory(options?: TargetKey | TargetKey[] | DestoryOptions): Promise<number>`
**参数**
| 参数名 | 类型 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `options.filterByTk` | `number \| string` | - | 查询主键 |
| `options.filter` | `Filter` | - | 查询条件 |
| `options.transaction?` | `Transaction` | - | 事务 |
`filterByTk``filter` 至少要传其一。如果没有传入事务参数,该方法会自动创建一个内部事务。
## 关系数据仓库类
通过 `db.getRepository('<name.associatedField>', <id>)` 方法获取到的关系数据仓库管理实例,在调用方法时,会自动在查询条件中加入当前表的主键值。除此以外,还拥有一些基于不同关系类型特有的成员和关系操作方法。
### `set()`
相当于 Sequelize 的 `record.setXxx()` 方法,用于设置关联数据。对一的关系参数为对应的外键,对多的关系参数为对应的外键数组。如果关系类型为 `BelongsToMany`,则会自动创建中间表数据。
**签名**
* `async set(association: string | number | string[] | number[]): Promise<void>`
**参数**
| 参数名 | 类型 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `association` | `string \| number \| string[] \| number[]` | - | 关联数据的外键,对多时可用数组 |
### `add()`
相当于 Sequelize 的 `record.addXxx()` 方法,用于附加关联,仅针对对多关系。
**签名**
* `async add(association: string | number | string[] | number[]): Promise<void>`
**参数**
| 参数名 | 类型 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `association` | `string \| number \| string[] \| number[]` | - | 关联数据的外键 |
### `remove()`
相当于 Sequelize 的 `record.removeXxx()` 方法,用于移除关联,仅针对对多关系。
**签名**
* `async remove(association: string | number | string[] | number[]): Promise<void>`
**参数**
| 参数名 | 类型 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `association` | `string \| number \| string[] \| number[]` | - | 关联数据的外键 |