数据库
Nest
与数据库无关,可以轻松地与任何 SQL
或 NoSQL
数据库集成:
- 为数据库加载一个适当的
Node.js
驱动程序。 - 直接使用任何通用的
Node.js
数据库集成库或ORM
,如:Sequelize (recipe)、knexjs(tutorial
)和 TypeORM ,以在更高的抽象级别上进行操作。 - 与现成的
TypeORM
(@nestjs/typeorm
)的紧密集成:这些集成提供了附加的特定于nestjs
的特性,比如模型/存储库注入、可测试性和异步配置,从而使访问您选择的数据库更加容易。
typeORM 集成
TypeORM 是 TypeScript
中最成熟的对象关系映射器(ORM
),提供了对许多关系数据库的支持,如:PostgreSQL
、Oracle
、Microsoft SQL Server
、SQLite
,甚至像 MongoDB
这样的 NoSQL
数据库。
Nest
提供了 @nestjs/typeorm
包。只需为所选数据库安装相关的客户端 API
库即可。
-
安装所需的依赖项。
npm install --save @nestjs/typeorm typeorm mysql2 复制代码
-
将
TypeOrmModule
导入AppModule
。// app.module.ts import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; @Module({ imports: [ TypeOrmModule.forRoot({ type: 'mysql', host: 'localhost', port: 3306, username: 'root', password: 'root', database: 'test', entities: [], synchronize: true, }), ], }) export class AppModule {} 复制代码
forRoot()
方法支持所有TypeORM
包中createConnection()
函数暴露出的配置属性,详见。参数 说明 retryAttempts
重试连接数据库的次数(默认:10) retryDelay
两次重试连接的间隔( ms
)(默认:3000)autoLoadEntities
自动加载实体标识(默认: false
,自动加载)keepConnectionAlive
在应用程序关闭后连接是否保持(默认: false
,关闭)或:创建
ormconfig.json
文件,然后不带任何选项地调用forRoot()
:// ormconfig.json { type: 'mysql', host: 'localhost', port: 3306, username: 'root', password: 'root', database: 'test', entities: [], synchronize: true, } 复制代码
// app.module.ts import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; @Module({ imports: [ TypeOrmModule.forRoot(), ], }) export class AppModule {} 复制代码
但是,
ormconfig.json
文件由typeorm
库载入,任何上述参数之外的属性都不会被应用。如:由forRoot()
方法内部支持的属性autoLoadEntities
和retryDelay()
。
存储库模式
TypeORM
支持存储库设计模式,因此每个实体都有自己的存储库。可以从数据库连接获得这些存储库(依赖包:typeorm-model-generator)。
实体
-
定义一个实体。
/** * @description: 真实PK用户清单实体文件 * @update: 2021-09-11 18:33:41 * @author: Ada.H */ // pk-user.entity.ts import { Entity, Column } from 'typeorm'; @Entity('user_is_kp_info', { schema: 'operator_data' }) export class PkUser { @Column('varchar', { primary: true, name: 'phone', comment: '电话', length: 16, }) phone: string @Column('varchar', { name: 'user_name', nullable: true, comment: '用户名称', length: 64, }) userName: string | null @Column('varchar', { name: 'post_name', nullable: true, comment: '角色', length: 512, }) postName: string | null @Column('varchar', { name: 'is_kp', comment: '是否kp用户', length: 2, default: () => "'1'", }) isKp: string @Column('datetime', { name: 'update_time', nullable: true, comment: '更新时间', default: () => 'CURRENT_TIMESTAMP', }) updateTime: Date | null @Column('datetime', { name: 'create_time', nullable: true, comment: '创建时间', }) createTime: Date | null } 复制代码
该
pk-user
实体在pk-users
目录下,该目录包含了和pk-users.module
模块有关的所有文件。可以自定义在哪里保存模型文件,但推荐在相应的模块目录中保存模型文件。 -
在模块的
forRoot()
方法的选项中将它插入entities
数组中来让TypeORM
知道它的存在。// app.module.ts import { PkUser } from './pk-users/pk-user.entity' // 非静态的全局路劲,手动单独插入 entities: [PkUser], // 静态的全局路径,无需单独插入 entities: ['dist/**/*.entity{.ts,.js}'], 复制代码
-
业务模块中使用
forFeature()
方法定义在当前范围中注册哪些存储库。// pk-users.module.ts import { Module } from '@nestjs/common' import { TypeOrmModule } from '@nestjs/typeorm' import { PkUsersService } from './pk-users.service' import { PkUsersController } from './pk-users.controller' import { PkUser } from './entities/pk-user.entity' @Module({ imports: [TypeOrmModule.forFeature([PkUser])], controllers: [PkUsersController], providers: [PkUsersService], }) export class PkUsersModule {} 复制代码
-
使用
@InjectRepository()
装饰器将PkUsersRepository
注入到PkUsersService
中。// pk-users.service.ts import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { PkUser } from './pk-user.entity'; @Injectable() export class PkUsersService { constructor( @InjectRepository(PkUser) private pkUsersRepository: Repository<PkUser> ) {} findAll(): Promise<PkUser[]> { return this.pkUsersRepository.find(); } findOne(id: string): Promise<PkUser> { return this.pkUsersRepository.findOne(id); } async remove(id: string): Promise<void> { await this.pkUsersRepository.delete(id); } } 复制代码