安装 typeorm、reflect-metadata、mysql2
yarn add typeorm reflect-metadata mysql2yarn add -D @types/reflect-metadata
开启 tsconfig.json 中的装饰器修饰
"emitDecoratorMetadata": true,"experimentalDecorators": true,
开启 es6 编译
tsconfig.json 中添加 lib 的 es6 支持,或者安装 @types/es6-shim
"lib": ["es6"]
创建配置文件 ormconfig.json
如果使用 typeorm –init 初始化配置文件,一定要注意:
- typeorm 需要安装在全局
- 不要在当前项目下执行命令,否则会覆盖掉当前项目的配置文件
建议在空目录执行此命令,把生成的配置文件拷贝到现有项目中
{ "type": "mysql", "host": "localhost", "port": 3306, "username": "root", "password": "123456", "database": "node-test", "synchronize": true, "logging": false, "entities": [ "src/entity/**/*.ts" ], "migrations": [ "src/migration/**/*.ts" ], "subscribers": [ "src/subscriber/**/*.ts" ], "cli": { "entitiesDir": "src/entity", "migrationsDir": "src/migration", "subscribersDir": "src/subscriber" }}
- synchronize:程序启动时是否同步模型数据。
- entities:要加载的实体类和目录路径。
- migrations:要加载的迁移类和目录。
- subscribers:要加载并用于此连接的订阅者的目录。
- cli.entitiesDir – CLI 默认情况下创建实体的目录。
- cli.migrationsDir – CLI 默认情况下创建迁移的目录。
- cli.subscribersDir – CLI 默认情况下创建订阅者的目录。
- 配置文档:https://typeorm.bootcss.com/connection-options
使用typeorm服务建立连接
// src/main.tsimport 'reflect-metadata';import { createConnection } from 'typeorm';createConnection().then(async (_) => { runServer(config.server.port);});
创建ORM模型
- 创建模型文件
// app/entiry/User.tsimport { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn } from 'typeorm';@Entity()export default class User { @PrimaryGeneratedColumn() // @ts-ignore id: number; @Column({ unique: true, nullable: false }) // @ts-ignore username: string; @Column({ nullable: false, length: 64 }) // @ts-ignore password: string; @Column() // @ts-ignore email: string; @CreateDateColumn() // @ts-ignore createdAt: Date;}
创建好模型后,此时启动服务器,将会在数据库中创建 user 表,因为我们在 ormconfig.json 中配置了 synchronize: true,会在服务启动的时候保持数据库和模型的同步,在实际项目开发中建议将此项关闭,防止误修改数据库。
使用ORM模型
在注册用户逻辑中使用 User 模型创建新的用户,用户注册逻辑如下:
- 参数校验
- 检查用户是否存在
- 创建新用户,并返回成功信息
参数校验
// src/controller/common/rules.tsexport const registRules: Rules = { username: { type: 'string', min: 8, required: true, }, password: { type: 'string', min: 8, required: true, }, confirm: { type: 'string', min: 8, required: true, validator: (_, value, callback, values) => { if (value !== values.password) { callback(new Error('两次密码不一致')); } callback(); }, }, email: { type: 'string', required: true, },};
// src/controller/common/types.tsexport interface RegisterParam { username: string; password: string; confirm: string; email: string;}
// src/controller/common/view.tsimport { RegisterParam } from './types';import { registRules } from './rules';async register(ctx: Context) { const { data, error } = await validate<RegisterParam>(ctx, registRules); if (error) { ctx.body = error return }}
检查用户是否存在
在 User 模型中添加静态方法:getUserInfo,根据用户名查询用户是否存在
// app/entity/User.tsimport { getRepository } from 'typeorm';import type { Repository } from 'typeorm';/** * @description 获取用户信息 * @param username 用户名 * @returns */static async getUserInfo(username: string) { const user: User | undefined = await getRepository(User).findOne({ username, }); return user;}
// src/controller/common/view.tsasync register(ctx: Context) { // 校验用户是否已经存在 const user: User | undefined = await User.getUserInfo(data.username); if (user) { response.error(ctx, '用户名已存在'); return; }}
创建新用户,并返回成功信息
在 User 模型中添加静态方法:createUser

/** * @description 创建用户 * @param user */static async createUser(user: User) { try { const userRepository: Repository<User> = getRepository(User); await userRepository.save(user); } catch (e) { throw e; }}
在用户注册逻辑中调用
// src/controll/common/view.tsasync register(ctx: Context) { ...... // 注册用户 user = new User(); user.username = data.username; user.password = data.password; user.email = data.email; await User.createUser(user); response.success(ctx, data, '注册成功');}
添加用户注册路由
// src/controller/common/router.tsrouter.post('/register', IndexController.register);