# @eggjs/dal-plugin 中文文档

规范地址：https://npmcn.com/package/%40eggjs/dal-plugin/

版本：4\.1\.0
npm 元数据更新时间：2026-10-07T08:25:06.367Z
中文译文更新时间：2026-11-13T12:47:43.111Z
软件包许可：未声明

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40eggjs/dal-plugin
原文对照：https://npmcn.com/package/%40eggjs/dal-plugin/?lang=original
项目主页：https://github.com/eggjs/egg/tree/next/tegg/plugin/dal
源码仓库：https://github.com/eggjs/egg

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：42.6 kB，25 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22\.18\.0
- 运行依赖：10 个
- peer 依赖：@eggjs/tegg-plugin 4\.1\.0
- 首次发布：2025-10-23T16:54:10.348Z
- 最新版本发布：2026-10-07T08:25:06.021Z
- 近 30 天下载量：3885（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：39（近 12 个月 33 个）

## 中文简介

彩蛋的 dal 插件

## 安装

```sh
npm install @eggjs/dal-plugin
```

也可以使用：`pnpm add @eggjs/dal-plugin`、`yarn add @eggjs/dal-plugin`、`bun add @eggjs/dal-plugin`

## README

# @eggjs/dal-plugin

[![NPM version](https://img.shields.io/npm/v/@eggjs/dal-plugin.svg?style=flat-square)](https://npmjs.org/package/@eggjs/dal-plugin) [![Known Vulnerabilities](https://snyk.io/test/npm/@eggjs/dal-plugin/badge.svg?style=flat-square)](https://snyk.io/test/npm/@eggjs/dal-plugin) [![npm download](https://img.shields.io/npm/dm/@eggjs/dal-plugin.svg?style=flat-square)](https://npmjs.org/package/@eggjs/dal-plugin) [![Node.js Version](https://img.shields.io/node/v/@eggjs/dal-plugin.svg?style=flat)](https://nodejs.org/en/download/)

@eggjs/dal-plugin 支持使用注解的方式来开发 egg 中的 dal。

## egg 模式

### Install

```shell
# tegg 注解
npm i --save @eggjs/tegg
# tegg 插件
npm i --save @eggjs/tegg-plugin
# tegg dal 插件
npm i --save @eggjs/dal-plugin
```

### Prepare

```json
// tsconfig.json
{
  "extends": "@eggjs/tsconfig"
}
```

### Config

```js
// config/plugin.js
exports.tegg = {
  package: '@eggjs/tegg-plugin',
  enable: true,
};

exports.teggDal = {
  package: '@eggjs/dal-plugin',
  enable: true,
};
```

## standalone 模式

### Install

```shell
# tegg 注解
npm i --save @eggjs/tegg
# tegg dal 插件
npm i --save @eggjs/dal-plugin
```

### Prepare

```json
// tsconfig.json
{
  "extends": "@eggjs/tsconfig"
}
```

## Usage

### module.yml

通过 module.yml 来配置 module 中的 mysql 数据源。

```yaml
dataSource:
  # 数据源名称，可以在 @Table 注解中指定
  # 如果 module 中只有一个 dataSource，@Table 会默认使用这个数据源
  foo:
    connectionLimit: 100
    database: 'test'
    host: '127.0.0.1'
    user: root
    port: 3306
```

### Table

`TableModel` 定义一个表结构，包括表配置、列、索引。

```ts
import { Table, Index, Column, ColumnType, IndexType } from '@eggjs/tegg/dal';

// 定义了一个表
@Table({
  comment: 'foo table',
})
// 定义了一个唯一索引，列是 name
@Index({
  keys: ['name'],
  type: IndexType.UNIQUE,
})
export class Foo {
  // 定义了主键，类型是 int
  @Column(
    {
      type: ColumnType.INT,
    },
    {
      primaryKey: true,
    },
  )
  id: number;

  // 定义了 name 列，类型是 varchar
  @Column({
    type: ColumnType.VARCHAR,
    length: 100,
  })
  name: string;
}
```

详细参数定义如下，具体参数值可以参考 [https://dev.mysql.com/doc/refman/8.0/en/create-table.html](https://dev.mysql.com/doc/refman/8.0/en/create-table.html)

建表参数，使用方式为 `@Table(parmas?: TableParams)`

```ts
export interface TableParams {
  // 数据库表名
  name?: string;
  // 数据源名称，如果 module 只有一个 dataSource 则默认使用这个
  dataSourceName?: string;
  comment?: string;
  autoExtendSize?: number;
  autoIncrement?: number;
  avgRowLength?: number;
  characterSet?: string;
  collate?: string;
  compression?: CompressionType;
  encryption?: boolean;
  engine?: string;
  engineAttribute?: string;
  insertMethod?: InsertMethod;
  keyBlockSize?: number;
  maxRows?: number;
  minRows?: number;
  rowFormat?: RowFormat;
  secondaryEngineAttribute?: string;
}
```

建索引参数，使用方式为 `@Index(parmas?: IndexParams)`

```ts
export interface IndexParams {
  // 索引的列
  keys: string[];
  // 索引名称，如果未指定会用 列名拼接
  // 如 [column1, column2 ]
  // 普通索引为 idx_column1_column2
  // 唯一索引为 uk_column1_column2
  name?: string;
  type?: IndexType;
  storeType?: IndexStoreType;
  comment?: string;
  engineAttribute?: string;
  secondaryEngineAttribute?: string;
  parser?: string;
}
```

建列参数，使用方式为 `@Column(type: ColumnTypeParams, parmas?: ColumnParams)`

```ts
export interface ColumnParams {
  // 列名，默认转换规则 userName 至 user_name
  name?: string;
  // 默认值
  default?: string;
  // 是否可控，默认为 false
  canNull?: boolean;
  comment?: string;
  visible?: boolean;
  autoIncrement?: boolean;
  uniqueKey?: boolean;
  primaryKey?: boolean;
  collate?: string;
  columnFormat?: ColumnFormat;
  engineAttribute?: string;
  secondaryEngineAttribute?: string;
}
```

支持的类型

```ts
export enum ColumnType {
  // Numeric
  BIT = 'BIT',
  TINYINT = 'TINYINT',
  BOOL = 'BOOL',
  SMALLINT = 'SMALLINT',
  MEDIUMINT = 'MEDIUMINT',
  INT = 'INT',
  BIGINT = 'BIGINT',
  DECIMAL = 'DECIMAL',
  FLOAT = 'FLOAT',
  DOUBLE = 'DOUBLE',
  // Date
  DATE = 'DATE',
  DATETIME = 'DATETIME',
  TIMESTAMP = 'TIMESTAMP',
  TIME = 'TIME',
  YEAR = 'YEAR',
  // String
  CHAR = 'CHAR',
  VARCHAR = 'VARCHAR',
  BINARY = 'BINARY',
  VARBINARY = 'VARBINARY',
  TINYBLOB = 'TINYBLOB',
  TINYTEXT = 'TINYTEXT',
  BLOB = 'BLOB',
  TEXT = 'TEXT',
  MEDIUMBLOB = 'MEDIUMBLOB',
  MEDIUMTEXT = 'MEDIUMTEXT',
  LONGBLOB = 'LONGBLOB',
  LONGTEXT = 'LONGTEXT',
  ENUM = 'ENUM',
  SET = 'SET',
  // JSON
  JSON = 'JSON',
  // Spatial
  GEOMETRY = 'GEOMETRY',
  POINT = 'POINT',
  LINESTRING = 'LINESTRING',
  POLYGON = 'POLYGON',
  MULTIPOINT = 'MULTIPOINT',
  MULTILINESTRING = 'MULTILINESTRING',
  MULTIPOLYGON = 'MULTIPOLYGON',
  GEOMETRYCOLLECTION = 'GEOMETRYCOLLECTION',
}
```

支持的类型参数，详细可参考 [https://dev.mysql.com/doc/refman/8.0/en/data-types.html](https://dev.mysql.com/doc/refman/8.0/en/data-types.html)

如果 mysql 类型和 ts 类型对应关系不确定可直接使用 `ColumnTsType` 类型，如

```ts
import { Table, Index, Column, ColumnType, IndexType, ColumnTsType } from '@eggjs/tegg/dal';

// 定义了一个表
@Table({
  comment: 'foo table',
})
// 定义了一个唯一索引，列是 name
@Index({
  keys: ['name'],
  type: IndexType.UNIQUE,
})
export class Foo {
  // 定义了主键，类型是 int
  @Column(
    {
      type: ColumnType.INT,
    },
    {
      primaryKey: true,
    },
  )
  id: ColumnTsType['INT'];

  // 定义了 name 列，类型是 varchar
  @Column({
    type: ColumnType.VARCHAR,
    length: 100,
  })
  name: ColumnTsType['VARCHAR'];
}
```

```ts
// Bit 类型，对应 js 中的 Buffer
export interface BitParams {
  type: ColumnType.BIT;
  // Bit 长度
  length?: number;
}

// Bool 类型，注意在 js 中需要使用 0 或者 1
export interface BoolParams {
  type: ColumnType.BOOL;
}

// TinyInt 类型，对应 js 中的 number
export interface TinyIntParams {
  type: ColumnType.TINYINT;
  length?: number;
  unsigned?: boolean;
  zeroFill?: boolean;
}

// SmallInt 类型，对应 js 中的 number
export interface SmallIntParams {
  type: ColumnType.SMALLINT;
  length?: number;
  unsigned?: boolean;
  zeroFill?: boolean;
}

// MediumInt 类型，对应 js 中的 number
export interface MediumIntParams {
  type: ColumnType.MEDIUMINT;
  length?: number;
  unsigned?: boolean;
  zeroFill?: boolean;
}

// MediumInt 类型，对应 js 中的 number
export interface IntParams {
  type: ColumnType.INT;
  length?: number;
  unsigned?: boolean;
  zeroFill?: boolean;
}

// BigInt 类型，对应 js 中的 string
export interface BigIntParams {
  type: ColumnType.BIGINT;
  length?: number;
  unsigned?: boolean;
  zeroFill?: boolean;
}

// Decimal 类型，对应 js 中的 string
export interface DecimalParams {
  type: ColumnType.DECIMAL;
  length?: number;
  fractionalLength?: number;
  unsigned?: boolean;
  zeroFill?: boolean;
}

// Float 类型，对应 js 中的 number
export interface FloatParams {
  type: ColumnType.FLOAT;
  length?: number;
  fractionalLength?: number;
  unsigned?: boolean;
  zeroFill?: boolean;
}

// Double 类型，对应 js 中的 number
export interface DoubleParams {
  type: ColumnType.DOUBLE;
  length?: number;
  fractionalLength?: number;
  unsigned?: boolean;
  zeroFill?: boolean;
}

// Date 类型，对应 js 中的 Date
export interface DateParams {
  type: ColumnType.DATE;
}

// DateTime 类型，对应 js 中的 Date
export interface DateTimeParams {
  type: ColumnType.DATETIME;
  precision?: number;
  // 自动添加 ON UPDATE CURRENT_TIMESTAMP
  // 如果有精度则为 ON UPDATE CURRENT_TIMESTAMP(precision)
  autoUpdate?: boolean;
}

// Timestamp 类型，对应 js 中的 Date
export interface TimestampParams {
  type: ColumnType.TIMESTAMP;
  precision?: number;
  // 自动添加 ON UPDATE CURRENT_TIMESTAMP
  // 如果有精度则为 ON UPDATE CURRENT_TIMESTAMP(precision)
  autoUpdate?: boolean;
}

// Times 类型，对应 js 中的 string
export interface TimeParams {
  type: ColumnType.TIME;
  precision?: number;
}

// Year 类型，对应 js 中的 number
export interface YearParams {
  type: ColumnType.YEAR;
}

// Char 类型，对应 js 中的 string
export interface CharParams {
  type: ColumnType.CHAR;
  length?: number;
  characterSet?: string;
  collate?: string;
}

// VarChar 类型，对应 js 中的 string
export interface VarCharParams {
  type: ColumnType.VARCHAR;
  length: number;
  characterSet?: string;
  collate?: string;
}

// Binary 类型，对应 js 中的 Buffer
export interface BinaryParams {
  type: ColumnType.BINARY;
  length?: number;
}

// VarBinary 类型，对应 js 中的 Buffer
export interface VarBinaryParams {
  type: ColumnType.VARBINARY;
  length: number;
}

// TinyBlob 类型，对应 js 中的 Buffer
export interface TinyBlobParams {
  type: ColumnType.TINYBLOB;
}

// TinyText 类型，对应 js 中的 string
export interface TinyTextParams {
  type: ColumnType.TINYTEXT;
  characterSet?: string;
  collate?: string;
}

// Blob 类型，对应 js 中的 Buffer
export interface BlobParams {
  type: ColumnType.BLOB;
  length?: number;
}

// Text 类型，对应 js 中的 string
export interface TextParams {
  type: ColumnType.TEXT;
  length?: number;
  characterSet?: string;
  collate?: string;
}

// MediumBlob 类型，对应 js 中的 Buffer
export interface MediumBlobParams {
  type: ColumnType.MEDIUMBLOB;
}

// LongBlob 类型，对应 js 中的 Buffer
export interface LongBlobParams {
  type: ColumnType.LONGBLOB;
}

// MediumText 类型，对应 js 中的 string
export interface MediumTextParams {
  type: ColumnType.MEDIUMTEXT;
  characterSet?: string;
  collate?: string;
}

// LongText 类型，对应 js 中的 string
export interface LongTextParams {
  type: ColumnType.LONGTEXT;
  characterSet?: string;
  collate?: string;
}

// Enum 类型，对应 js 中的 string
export interface EnumParams {
  type: ColumnType.ENUM;
  enums: string[];
  characterSet?: string;
  collate?: string;
}

// Set 类型，对应 js 中的 string
export interface SetParams {
  type: ColumnType.SET;
  enums: string[];
  characterSet?: string;
  collate?: string;
}

// Json 类型，对应 js 中的 Object
export interface JsonParams {
  type: ColumnType.JSON;
}

// Gemotry 类型，对应 Point, Line, Polygon
export interface GeometryParams {
  type: ColumnType.GEOMETRY;
  SRID?: number;
}

export interface PointParams {
  type: ColumnType.POINT;
  SRID?: number;
}

export interface LinestringParams {
  type: ColumnType.LINESTRING;
  SRID?: number;
}

export interface PolygonParams {
  type: ColumnType.POLYGON;
  SRID?: number;
}

export interface MultiPointParams {
  type: ColumnType.MULTIPOINT;
  SRID?: number;
}

export interface MultiLinestringParams {
  type: ColumnType.MULTILINESTRING;
  SRID?: number;
}

export interface MultiPolygonParams {
  type: ColumnType.MULTIPOLYGON;
  SRID?: number;
}

// GeometryCollection 对应 Array<Point | Line | Ploygon>
export interface GeometryCollectionParams {
  type: ColumnType.GEOMETRYCOLLECTION;
  SRID?: number;
}
```

### 目录结构

运行 `egg-bin dal gen` 即可生成 `dal` 相关目录，包括 dao、extension、structure

```plain
dal
├── dao
│ ├── FooDAO.ts
│ └── base
│     └── BaseFooDAO.ts
├── extension
│ └── FooExtension.ts
└── structure
    ├── Foo.json
    └── Foo.sql
```

-   dao: 表访问类，生成的 BaseDAO 请勿修改，其中包含了根据表结构生成的基础访问方法，如 insert/update/delete 以及根据索引信息生成的 find 方法
-   extension: 扩展文件，如果需要自定义 sql，需要在 extension 文件中定义
-   structure: 建表语句以及表结构

### DAO

注入 DAO 即可实现对表的访问

```ts
import { SingletonProto, Inject } from '@eggjs/tegg';

@SingletonProto()
export class FooRepository {
  @Inject()
  private readonly fooDAO: FooDAO;

  async create(foo: Foo) {
    await this.fooDAO.insert(foo);
  }
}
```

#### 自定义 SQL

1.  在 extension 中定义自定义 SQL

```ts
// dal/extension/FooExtension.ts
import { type SqlMap, SqlType } from '@eggjs/tegg/dal';

export default {
  findByName: {
    type: SqlType.SELECT,
    sql: 'SELECT {{ allColumns }} FROM egg_foo WHERE name = {{ name }}',
  },
} as Record<string, SqlMap>;
```

2.  在 dao 中定义自定义方法

```ts
import { SingletonProto, AccessLevel } from '@eggjs/tegg';
import { BaseFooDAO } from './base/BaseFooDAO';
import { Foo } from '../../Foo';

@SingletonProto({
  accessLevel: AccessLevel.PUBLIC,
})
export default class FooDAO extends BaseFooDAO {
  async findByName(name: string): Promise<Foo[]> {
    return this.dataSource.execute('findByName', {
      name,
    });
  }
}
```

支持的自定义 filter

```
- toPoint
- toLine
- toPolygon
- toGeometry
- toMultiPoint
- toMultiLine
- toMultiPolygon
- toGeometryCollection
```

支持自定义 block 来简化 sql, 如内置的 allColumns

```ts
export default {
  findByName: {
    type: SqlType.BLOCK,
    sql: 'id, name',
  },
} as Record<string, SqlMap>;
```

### DataSource

DataSource 仅能在 DAO 中使用，可以将 MySQL 返回的数据反序列化为类。支持的方法有

```ts
export interface DataSource<T> {
  // 将返回的行都转换为 T
  execute(sqlName: string, data?: any): Promise<Array<T>>;
  // 将返回的行都转换为 T, 仅返回第一条
  executeScalar(sqlName: string, data?: any): Promise<T | null>;
  // 直接返回 mysql 数据
  executeRaw(sqlName: string, data?: any): Promise<Array<any>>;
  // 直接返回 mysql 数据, 仅返回第一条
  executeRawScalar(sqlName: string, data?: any): Promise<any | null>;
  // 返回分页数据
  paginate(sqlName: string, data: any, currentPage: number, perPageCount: number): Promise<any>;
  // 返回行数
  count(sqlName: string, data?: any): Promise<number>;
}
```

### 时区问题

注意连接配置中的时区必须和数据库的时区完全一致，否则可能出现时间错误的问题。

```yaml
dataSource:
  foo:
    connectionLimit: 100
    database: 'test'
    host: '127.0.0.1'
    user: root
    port: 3306
    timezone: '+08:00'
```

可以通过以下 SQL 来查看数据库时区

```sql
SELECT @@GLOBAL.time_zone;
```

## Unittest

可以在 `module.yml` 中开启 forkDb 配置，即可实现 unittest 环境自动创建数据库

```yaml
# module.yml
dataSource:
  foo:
    # 开启 ci 环境自动创建数据库
    forkDb: true
```

## 常见问题

### @eggjs/dal-plugin 是什么？

彩蛋的 dal 插件

### 如何安装 @eggjs/dal-plugin？

在项目目录运行 npm install @eggjs/dal-plugin，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：@eggjs/tegg-plugin（4\.1\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @eggjs/dal-plugin 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @eggjs/dal-plugin 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @eggjs/dal-plugin 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=22\.18\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @eggjs/dal-plugin 可以商用吗？

@eggjs/dal-plugin 使用 未声明 许可。package\.json 没有声明许可证。没有许可证的代码默认保留全部权利，商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括，不构成法律意见，请以许可原文为准。

### @eggjs/dal-plugin 的下载量有多少？

根据 npm 官方下载统计，@eggjs/dal-plugin 在 2026/10/13 – 2026/11/11 这 30 天内被下载 3,885 次，日均约 130 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @eggjs/dal-plugin 还在维护吗？

最新版本 4\.1\.0 发布于 2026/10/07（1 个月前）；至今共发布 39 个版本，其中过去 12 个月发布了 33 个；首次发布于 2025/10/24。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

