前言
本篇文章主要来记录下NestJs
如何连接数据库,不要问问啥要连数据库。服务端应用不连数据库难道只写Hello World吗。至于数据库还是选择了MySQL
,王道!别问Oracle
,问就是收钱。至于连接工具,这里选择了NestJs推荐的TypeORM
,当然,这里完全自由啊,如果有同学喜欢其他的工具也是完全可以的。
环境准备
MySQL
既然要连数据库,肯定得先有数据库哈。这里我直接使用了我自己云端的数据库,有个人服务器的同学建议直接使用远程的,没有的同学也可以在本机装一个MySQL
服务,安装方式这里就不介绍了,大家可自行问度娘。
- 新建数据库以及数据表
首先我们新建一个
test
库,然后在这个库里新建一个user
表。BTW,这里其实可以使用可视化工具来操作的哈,个人感觉比较好用的还是Navicat
,我这里因为不方便安装,所以直接访问的服务。
这就是建好表之后的样子了,然后我们在表里先插入一条测试数据,方便等会测试数据库连接。
到这里,数据库的准备基本结束了。
TypeORM
TypeORM 是一个ORM (opens new window)框架,它可以运行在 NodeJS、Browser、Cordova、PhoneGap、Ionic、React Native、Expo 和 Electron 平台上,可以与 TypeScript 和 JavaScript (ES5,ES6,ES7,ES8)一起使用。 它的目标是始终支持最新的 JavaScript 特性并提供额外的特性以帮助你开发任何使用数据库的(不管是只有几张表的小型应用还是拥有多数据库的大型企业应用)应用程序。
不同于现有的所有其他 JavaScript ORM 框架,TypeORM 支持 Active Record](active-record-data-mapper.md#what-is-the-active-record-pattern) 和 Data Mapper 模式,这意味着你可以以最高效的方式编写高质量的、松耦合的、可扩展的、可维护的应用程序。 -- TypeORM中文文档
关于一些修饰器的定义和用方法,本文不会再详细介绍了,大家有问题可以去查询下TypeORM中文文档
- 安装
# yarn
@nestjs/typeorm typeorm mysql
#npm
npm install --save @nestjs/typeorm typeorm mysql
项目配置
创建实体
我们首先在项目根路径下创建entities
文件夹,后续新增的eneity
文件都会放到这里面,里面也可以再根据业务来区分模块。
然后我们新建一个user.eneity.ts
文件
- user.entity.ts
import { Column, Entity, PrimaryGeneratedColumn, BaseEntity } from 'typeorm';
@Entity()
export class UserEntity extends BaseEntity {
// 自增主键
@PrimaryGeneratedColumn()
id: number;
// 列
@Column({ type: 'varchar', name: 'userName' })
userName: string;
@Column({ type: 'varchar', name: 'userPwd' })
// 此处key可自定义,在项目中使用的key
userPwd: string;
}
如果不需要做列名映射的话,其实这里可以简写成@Column(type)
,type建议还是不要省略了。至于继承的BaseEneity
实体,这是TypeORM
提供的基础实体,里面有一些封装好的简单的CRUD方法,如果有接触过Hibernate
的同学应该对这里比较容易理解。有兴趣的同学也可以去看下这个实体里面具体都封装了哪些方法,有些简单的业务或许可以用到。
数据库配置
既然想使用数据库,那么肯定需要先连接。这里有两种方式。可以使用配置文件或者在app.moudle.ts
中直连。
- 配置文件
在项目根路径下新增
ormconfig.json
文件
{
"type": "mysql", // 数据库类型
"host": "localhost", // 数据库地址
"port": 3306, // 端口号,如果没有自定义的话,这里默认就是3306
"username": "test", // 用户名
"password": "test", // 密码
"database": "test", // 需要连接的数据库
"synchronize": true, // 数据库与实体同步(如果在实体中新增的字段,那么数据库对应表里会自动插入)
"entities": ["src/entity/**/*.ts"], // 实体扫描路径
}
其余的配置项这里就不详细介绍了,可按需查文档
- app.module.ts 我是采用了这种方式,配置文件中配置动态路径会稍微复杂一点~~
...
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({ // 配置写在这里
type: 'mysql',
host: '***.***.***.***',
port: 3306,
username: 'root',
password: '************',
database: 'test',
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true,
}),
...
],
...
})
export class AppModule {}
PS:...代表的是没有变更的代码,不是真的...
新增测试接口
- user.module.ts
import { Module } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { UserEntity } from '@/entities/system/user.entity';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [TypeOrmModule.forFeature([UserEntity])],
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}
PS2: 每一个实体文件都需要在其对应模块中导入并使用TypeOrmModule.forFeature()
注册
- user.service.ts 我们在这里注入实体并编写一个测试方法
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { UserEntity } from '@/entities/system/user.entity';
@Injectable()
export class UserService {
// 在构造方法中注入实体
constructor(
@InjectRepository(UserEntity)
private readonly userRepository: Repository<UserEntity>,
) {}
...
// 在这里新增一个getAll方法,测试配置是否正确
async getAllUserTest(): Promise<UserEntity[]> {
// 其实这里也可以使用BaseEntity里提供的Read方法,不过建议还是自己写SQL比较好
return await this.userRepository.query('select * from user');
}
}
- user.controller.ts 最后在controller中新增一个测试接口
...
@Controller('user')
@ApiTags('用户操作')
export class UserController {
...
@Get('get_all_list')
findAll(): any {
return this.userService.getAllUserTest();
}
}
测试
首先运行 yarn start:dev
启动项目
然后通过工具请求一下刚定义的接口
OK,可以看到正常返回了正确的结果。那么本篇文章就到此结束了~~~
PS: 下集预告:引入JWT实现登录验证