D6 的训练一开始会去创建一个全新的 Nest.js 项目,然后配置好项目需要的数据服务,创建一个模块,模块里定义一种实体,实体上添加几个需要的数据字段。
Nest.js 框架里集成使用了 TypeORM,ORM 可以想成是一种定义与处理数据用的方法,TypeORM 是其中的一种 ORM,可以让我们用 TypeScript 或 JavaScript 处理数据库里的数据。所以暂时可以把 TypeORM 想成是一套定义与处理数据用的方法或工具,在 Nest.js 框架里集成使用了它。
往后的训练会经常用到数据的处理,所以 D6 的训练非常关键,就是准备一个可用的数据服务,然后配置好 Nest.js 框架能够正常的使用这个数据服务,比如可以通过定义实体在应用的数据库里添加一个数据表,数据表里有实体中描述的数据字段。
在训练中,我们会用 Docker 去创建一个 MySQL 数据服务,TypeORM 支持处理多种不同类型的关系型数据库,MySQL 是其中的一种。你也可以选择使用 MariaDB、PostgreSQL 等等。
如果你发现在自己的电脑上无法正常运行 Docker,可以选择使用其它的方式去创建应用需要的数据服务,比如直接在电脑上安装一个 MySQL 数据库系统,或者使用一些集成环境里带的 MySQL,也可以使用远程服务器上的 MySQL,只要你有权限创建并管理其中的一个数据库就可以了。
安装
在 Nest.js 框架里使用 TypeORM 提供的数据处理方法,需要去安装几个包:
npm install @nestjs/typeorm typeorm mysql --save
上面安装了 @nestjs/typeorm,这个包里提供的功能集成使用了 TypeORM,typeorm 是 TypeORM 本身, mysql 这个包提供了操作 MySQL 类型的数据库的方法,TypeORM 会用到它提供的功能。
配置
在应用的 AppModule 里可以配置使用一下 TypeORM:
import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { AppController } from './app.controller'; import { AppService } from './app.service'; @Module({ imports: [ TypeOrmModule.forRoot({ type: 'mysql', host: 'localhost', port: 3306, username: 'nest', password: 'password', database: 'nest', synchronize: true, entities: [__dirname + '/**/*.entity{.ts,.js}'] }) ], controllers: [AppController], providers: [AppService], }) export class AppModule {}
先导入 @nestjs/typeorm 这个包里提供的 TypeOrmModule 模块,然后在这个 AppModule 里导入使用它,用一下它上面的 forRoot 方法,给它提供一个配置对象,在这个配置对象里,可以配置要使用的数据库的类型,主机,用户等等相关的信息。 entities 设置的是应用里定义的实体,TypeORM 会根据这些实体的定义去在数据库里创建对应数据表。
上面的配置信息我们也可以放在 .env 这个环境变量文件里,先去掉给 TypeOrmModule.forRoot 方法提供的配置对象,然后在项目的根目录下面,创建一个 .env 文件,把下面的内容放进去(根据自己的实体情况进行修改):
# TypeORM TYPEORM_CONNECTION=mysql TYPEORM_HOST=localhost TYPEORM_PORT=3306 TYPEORM_USERNAME=nest TYPEORM_PASSWORD=password TYPEORM_DATABASE=nest TYPEORM_SYNCHRONIZE=true TYPEORM_LOGGING=true TYPEORM_ENTITIES=**/modules/**/*.entity.js
实体
实体(Entity)就是在应用里面出现的一些资源,或者叫一种东西,比如内容、评论、用户、分类、标签等等,这些都可以看成是应用里的实体。这些资源需要对应的数据表去存储相关的数据,我们可以在定义实体的文件里描述一下,每一种实体都需要哪些数据字段,TypeORM 会根据实体的定义去创建对应的数据表,在表里添加需要的字段。
下面是一个实体示例:
import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm'; @Entity() export class Post { @PrimaryGeneratedColumn() id: number; @Column() title: string; @Column('longtext') body: string; @CreateDateColumn() created: Date; @UpdateDateColumn() updated: Date; }
上面定义了一个叫 Post 的实体,所以默认会在应用的数据库里创建一个叫 post 的数据表。在这个实体里有几个字段,id、title、body、created 还有 updated,添加这些字段的时候都用了特定的装饰器,这些装饰器的作用就是描述一下它装饰的字段,比如它的类型是什么。这些装饰器都来自 typeorm 这个包。
运行项目的开发服务以后,会自动在应用的数据库里创建一个叫 post 的数据表,这个表里会出现在实体定义中添加的那几个数据字段。