数据库
Deepkit 具有自己强大的数据库抽象库,称为 Deepkit ORM。它是一款对象关系映射(ORM)库,可简化与 SQL 数据库和 MongoDB 的协作。
虽然你可以使用任意数据库库,但我们推荐 Deepkit ORM,因为它是最快的 TypeScript 数据库抽象库,与 Deepkit 框架深度集成,并拥有许多能提升工作流程与效率的特性。
本章解释如何在你的 Deepkit 应用中使用 Deepkit ORM。有关 Deepkit ORM 的完整信息,请参阅ORM章节。
数据库类
在应用中使用 Deepkit ORM 的 Database
对象的最简单方式,是注册一个从其派生的类。
import { Database } from '@deepkit/orm'; import { SQLiteDatabaseAdapter } from '@deepkit/sqlite'; import { User } from './models'; export class SQLiteDatabase extends Database { constructor() { super( new SQLiteDatabaseAdapter('/tmp/myapp.sqlite'), [User] ); } }
创建一个新类,并在其构造函数中指定适配器及其参数;同时在第二个参数中添加所有应连接到此数据库的实体模型。
现在你可以将该数据库类注册为提供者(provider)。我们还启用 migrateOnStartup
,它会在启动时自动在你的数据库中创建所有表。这非常适合快速原型开发,但不建议用于严肃项目或生产环境。此时应使用常规的数据库迁移。
我们还启用 debug
,这样在应用服务器启动时可以打开调试器,并在内置的 ORM 浏览器中直接管理你的数据库模型。
import { App } from '@deepkit/app'; import { FrameworkModule } from '@deepkit/framework'; import { SQLiteDatabase } from './database.ts'; new App({ providers: [SQLiteDatabase], imports: [ new FrameworkModule({ migrateOnStartup: true, debug: true, }) ] }).run();
现在你可以通过依赖注入在任意位置访问 SQLiteDatabase
:
import { SQLiteDatabase } from './database.ts'; export class Controller { constructor(protected database: SQLiteDatabase) {} @http.GET() async startPage(): Promise<User[]> { //返回所有用户 return await this.database.query(User).find(); } }
配置
在许多情况下,你希望连接凭据是可配置的。比如,测试环境与生产环境使用不同的数据库。你可以通过 Database
类的 config
选项来实现。
//database.ts import { Database } from '@deepkit/orm'; import { PostgresDatabaseAdapter } from '@deepkit/sqlite'; import { User } from './models'; type DbConfig = Pick<AppConfig, 'databaseHost', 'databaseUser', 'databasePassword'>; export class MainDatabase extends Database { constructor(config: DbConfig) { super(new PostgresDatabaseAdapter({ host: config.databaseHost, user: config.databaseUser, password: config.databasePassword, }), [User]); } }
//config.ts export class AppConfig { databaseHost: string = 'localhost'; databaseUser: string = 'postgres'; databasePassword: string = ''; }
//app.ts import { App } from '@deepkit/app'; import { FrameworkModule } from '@deepkit/framework'; import { MainDatabase } from './database.ts'; import { AppConfig } from './config.ts'; const app = new App({ config: AppConfig, providers: [MainDatabase], imports: [ new FrameworkModule({ migrateOnStartup: true, debug: true, }) ] }); app.loadConfigFromEnv({prefix: 'APP_', namingStrategy: 'upper', envFilePath: ['local.env', 'prod.env']}); app.run();
现在,由于我们使用了 loadConfigFromEnv,我们可以通过环境变量来设置数据库凭据。
APP_DATABASE_HOST=localhost APP_DATABASE_USER=postgres ts-node app.ts server:start
或者在 local.env
文件中设置,并在未预先设置任何环境变量的情况下启动 ts-node app.ts server:start
。
APP_DATABASE_HOST=localhost APP_DATABASE_USER=postgres
多个数据库
你可以按需添加任意数量的数据库类,并为它们任意命名。请确保修改每个数据库的名称,以免在使用 Deepkit ORM 浏览器时与其他数据库冲突。
管理数据
现在你已经完成所有设置,可以使用 Deepkit ORM 浏览器来管理你的数据库数据。要打开 Deepkit ORM 浏览器并管理内容,请将上述所有步骤写入 app.ts
文件并启动服务器。
$ ts-node app.ts server:start 2021-06-11T15:08:54.330Z [LOG] Start HTTP server, using 1 workers. 2021-06-11T15:08:54.333Z [LOG] Migrate database default 2021-06-11T15:08:54.336Z [LOG] RPC DebugController deepkit/debug/controller 2021-06-11T15:08:54.337Z [LOG] RPC OrmBrowserController orm-browser/controller 2021-06-11T15:08:54.337Z [LOG] HTTP OrmBrowserController 2021-06-11T15:08:54.337Z [LOG] GET /_orm-browser/query httpQuery 2021-06-11T15:08:54.337Z [LOG] HTTP StaticController 2021-06-11T15:08:54.337Z [LOG] GET /_debug/:any serviceApp 2021-06-11T15:08:54.337Z [LOG] HTTP listening at http://localhost:8080/
现在你可以打开 http://localhost:8080/_debug/database/default。

你可以看到 ER(实体关系)图。目前只有一个实体可用。如果你添加了更多带关系的实体,你将一目了然地看到所有信息。
如果你在左侧侧栏点击 User
,即可管理其内容。点击 +
图标并修改新记录的标题。更改所需的值(例如用户名)后,点击 Confirm
。这会将所有更改提交到数据库并使之生效。自增 ID 会自动分配。

进一步了解
要进一步了解 SQLiteDatabase
的工作方式,请阅读数据库一章及其子章节,例如查询数据、通过会话操作数据、定义关系等。
请注意,那些章节针对的是独立库 @deepkit/orm
,并不包含本章上文所述的 Deepkit 框架部分的文档。在独立库中,你需要手动实例化数据库类,例如通过 new SQLiteDatabase()
。然而,在你的 Deepkit 应用中,这由依赖注入容器自动完成。
迁移
Deepkit 框架提供了强大的迁移系统,允许你创建、执行和回滚迁移。该迁移系统基于 Deepkit ORM 库,因此与框架完美集成。
FrameworkModule
提供了多个用于管理迁移的命令。
migration:create
- 基于数据库差异生成新的迁移文件migration:pending
- 显示待执行的迁移文件migration:up
- 执行待执行的迁移文件migration:down
- 执行向下迁移,回滚旧的迁移文件
ts-node app.ts migration:create --migrationDir src/migrations
一个新的迁移文件会创建在 migrations
目录中。该目录是 FrameworkModule 中配置的默认目录。要更改它,可以通过环境变量(如配置一章所述)修改配置,或在构造 FrameworkModule
时传入 migrationDir
选项。
new FrameworkModule({ migrationDir: 'src/migrations', })
新创建的迁移文件现在包含 up 和 down 方法,它们基于你的 TypeScript 应用中定义的实体与已配置数据库之间的差异生成。 你可以根据需要修改 up 方法。down 方法会基于 up 方法自动生成。 将该文件提交到你的代码仓库,以便其他开发者也能执行它。
待执行的迁移
ts-node app.ts migration:pending --migrationDir src/migrations
这会显示所有待执行的迁移。如果你有尚未执行的新迁移文件,它会列在这里。
执行迁移
ts-node app.ts migration:up --migrationDir src/migrations
这将执行下一个待执行的迁移。
回滚迁移
ts-node app.ts migration:down --migrationDir src/migrations
这将回滚上一次执行的迁移。
伪迁移
假设你尝试执行一次迁移(向上或向下),但失败了。你手动修复了问题,但现在无法再次执行该迁移,因为它已被标记为已执行。此时可以使用 --fake
选项来伪装执行:在不实际执行的情况下,将该迁移在数据库中标记为已执行。这样你就可以继续执行下一个待执行的迁移。
ts-node app.ts migration:up --migrationDir src/migrations --fake