当前位置:   article > 正文

nestjs从零到一,快速上手(三):typeorm的使用_nestjs 集成typeorm

nestjs 集成typeorm

1. typeorm的使用(以下示例均可参考代码:https://github.com/guorunfa/nestjs-temp)

中文文档: https://typeorm.bootcss.com/icon-default.png?t=N7T8https://typeorm.bootcss.com/

一对一

一对一是一种 A 只包含一个 B 实例,而 B 只包含一个 A 实例的关系。 我们以UserProfile实体为例。

用户只能拥有一个配置文件,并且一个配置文件仅由一个用户拥有。

  1. import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
  2. @Entity()
  3. export class Profile {
  4. @PrimaryGeneratedColumn()
  5. id: number;
  6. @Column()
  7. gender: string;
  8. @Column()
  9. photo: string;
  10. }
  1. import { Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn } from "typeorm";
  2. import { Profile } from "./Profile";
  3. @Entity()
  4. export class User {
  5. @PrimaryGeneratedColumn()
  6. id: number;
  7. @Column()
  8. name: string;
  9. @OneToOne(() => Profile)
  10. @JoinColumn()
  11. profile: Profile;
  12. }

这里我们将@OneToOne添加到profile并将目标关系类型指定为Profile。 我们还添加了@JoinColumn,这是必选项并且只能在关系的一侧设置。 你设置@JoinColumn的哪一方,哪一方的表将包含一个"relation id"和目标实体表的外键。

此示例将生成以下表:

  1. +-------------+--------------+----------------------------+
  2. | profile |
  3. +-------------+--------------+----------------------------+
  4. | id | int(11) | PRIMARY KEY AUTO_INCREMENT |
  5. | gender | varchar(255) | |
  6. | photo | varchar(255) | |
  7. +-------------+--------------+----------------------------+
  8. +-------------+--------------+----------------------------+
  9. | user |
  10. +-------------+--------------+----------------------------+
  11. | id | int(11) | PRIMARY KEY AUTO_INCREMENT |
  12. | name | varchar(255) | |
  13. | profileId | int(11) | FOREIGN KEY |
  14. +-------------+--------------+----------------------------+

多对一/一对多的关系

多对一/一对多是指 A 包含多个 B 实例的关系,但 B 只包含一个 A 实例。 让我们以User 和 Photo 实体为例。 User 可以拥有多张 photos,但每张 photo 仅由一位 user 拥有。

  1. import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from "typeorm";
  2. import { User } from "./User";
  3. @Entity()
  4. export class Photo {
  5. @PrimaryGeneratedColumn()
  6. id: number;
  7. @Column()
  8. url: string;
  9. @ManyToOne(() => User, user => user.photos)
  10. user: User;
  11. }
  1. import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";
  2. import { Photo } from "./Photo";
  3. @Entity()
  4. export class User {
  5. @PrimaryGeneratedColumn()
  6. id: number;
  7. @Column()
  8. name: string;
  9. @OneToMany(() => Photo, photo => photo.user)
  10. photos: Photo[];
  11. }

这里我们将@OneToMany添加到photos属性中,并将目标关系类型指定为Photo。 你可以在@ManyToOne / @OneToMany关系中省略@JoinColumn,除非你需要自定义关联列在数据库中的名称。 @ManyToOne可以单独使用,但@OneToMany必须搭配@ManyToOne使用。 如果你想使用@OneToMany,则需要@ManyToOne。 在你设置@ManyToOne的地方,相关实体将有"关联 id"和外键。

此示例将生成以下表:

  1. +-------------+--------------+----------------------------+
  2. | photo |
  3. +-------------+--------------+----------------------------+
  4. | id | int(11) | PRIMARY KEY AUTO_INCREMENT |
  5. | url | varchar(255) | |
  6. | userId | int(11) | |
  7. +-------------+--------------+----------------------------+
  8. +-------------+--------------+----------------------------+
  9. | user |
  10. +-------------+--------------+----------------------------+
  11. | id | int(11) | PRIMARY KEY AUTO_INCREMENT |
  12. | name | varchar(255) | |
  13. +-------------+--------------+----------------------------+

多对多的关系

多对多是一种 A 包含多个 B 实例,而 B 包含多个 A 实例的关系。 我们以Question 和 Category 实体为例。 Question 可以有多个 categories, 每个 category 可以有多个 questions。

  1. import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
  2. @Entity()
  3. export class Category {
  4. @PrimaryGeneratedColumn()
  5. id: number;
  6. @Column()
  7. name: string;
  8. }
  1. import { Entity, PrimaryGeneratedColumn, Column, ManyToMany, JoinTable } from "typeorm";
  2. import { Category } from "./Category";
  3. @Entity()
  4. export class Question {
  5. @PrimaryGeneratedColumn()
  6. id: number;
  7. @Column()
  8. title: string;
  9. @Column()
  10. text: string;
  11. @ManyToMany(() => Category)
  12. @JoinTable()
  13. categories: Category[];
  14. }

@JoinTable()@ManyToMany关系所必需的。 你必须把@JoinTable放在关系的一个(拥有)方面。

此示例将生成以下表:

  1. +-------------+--------------+----------------------------+
  2. | category |
  3. +-------------+--------------+----------------------------+
  4. | id | int(11) | PRIMARY KEY AUTO_INCREMENT |
  5. | name | varchar(255) | |
  6. +-------------+--------------+----------------------------+
  7. +-------------+--------------+----------------------------+
  8. | question |
  9. +-------------+--------------+----------------------------+
  10. | id | int(11) | PRIMARY KEY AUTO_INCREMENT |
  11. | title | varchar(255) | |
  12. +-------------+--------------+----------------------------+
  13. +-------------+--------------+----------------------------+
  14. | question_categories_category |
  15. +-------------+--------------+----------------------------+
  16. | questionId | int(11) | PRIMARY KEY FOREIGN KEY |
  17. | categoryId | int(11) | PRIMARY KEY FOREIGN KEY |
  18. +-------------+--------------+----------------------------+

2.旧数据库利用typeorm快速迁移(使用typeorm-model-generator库)

typeorm-model-generatoricon-default.png?t=N7T8https://www.npmjs.com/package/typeorm-model-generator

Generates models for TypeORM from existing databases. Supported db engines:

  • Microsoft SQL Server
  • PostgreSQL
  • MySQL
  • MariaDB
  • Oracle Database
  • SQLite

1.安装 

pnpm i -D typeorm-model-generator

 2.在package.json里面配置运行的命令

"generate:models": typeorm-model-generator -h localhost -p 3306 -d testdb -u sa -x !Passw0rd -e mysql -o ./src

3.

pnpm generate:models

4. 在配置里更改数据库名称为mytest,可以把testdb数据库表同步到mytest数据库(更改完毕后,启动项目即可,注意此时数据没有同步!!!,只是数据库表)

3.typeorm增删改查(curd)

参考代码:文件user.controller.ts

  1. import {
  2. Controller,
  3. Get,
  4. Inject,
  5. LoggerService,
  6. Param,
  7. Post,
  8. Query,
  9. } from '@nestjs/common';
  10. import { UserService } from './user.service';
  11. import { ConfigService } from '@nestjs/config';
  12. import { User } from './user.entity';
  13. import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';
  14. @Controller('user')
  15. export class UserController {
  16. constructor(
  17. private userService: UserService,
  18. private configService: ConfigService,
  19. // @Inject(Logger) private readonly logger: LoggerService,
  20. @Inject(WINSTON_MODULE_NEST_PROVIDER)
  21. private readonly logger: LoggerService,
  22. ) {}
  23. @Get('/add')
  24. getUsers(): any {
  25. return this.userService.add();
  26. }
  27. @Post()
  28. addUser(): any {
  29. // todo 解析Body参数
  30. const user = { username: 'xxxx', password: '123456' } as User;
  31. return this.userService.create(user);
  32. }
  33. @Get('/update/:id')
  34. updateUser(@Param() params): any {
  35. const user = { username: 'newname' } as User;
  36. return this.userService.update(params.id, user);
  37. }
  38. @Get('/delete/:id')
  39. deleteUser(@Param('id') id: number): any {
  40. return this.userService.remove(id);
  41. }
  42. @Get('/find/:name')
  43. find(@Param() params): any {
  44. return this.userService.likeFind(params.name);
  45. }
  46. @Get('/profile')
  47. profile(): any {
  48. return this.userService.findProfile(5);
  49. }
  50. @Get('/logsByGroup')
  51. getLogsByGroup(): any {
  52. return this.userService.findLogsByGroup(5);
  53. }
  54. @Get('/')
  55. getUser(@Query() query: any): any {
  56. console.log(query);
  57. return this.userService.findAll();
  58. }
  59. }

参考代码:文件user.service.ts 

  1. import { Injectable } from '@nestjs/common';
  2. import { InjectRepository } from '@nestjs/typeorm';
  3. import { Like, Repository } from 'typeorm';
  4. import { User } from './user.entity';
  5. import { Logs } from '../logs/logs.entity';
  6. @Injectable()
  7. export class UserService {
  8. constructor(
  9. @InjectRepository(User) private readonly user: Repository<User>,
  10. @InjectRepository(Logs) private readonly logsRepository: Repository<Logs>,
  11. ) {}
  12. add() {
  13. // console.log(this.logsRepository);
  14. const data = new User();
  15. data.username = '小率';
  16. data.password = '123';
  17. return this.user.save(data);
  18. }
  19. findAll() {
  20. return this.user.find();
  21. }
  22. find(username: string) {
  23. return this.user.findOne({ where: { username } });
  24. }
  25. likeFind(username: string) {
  26. return this.user.find({
  27. where: { username: Like(`%${username}%`) },
  28. });
  29. }
  30. async create(user: User) {
  31. const userTmp = await this.user.create(user);
  32. return this.user.save(userTmp);
  33. }
  34. async update(id: number, user: Partial<User>) {
  35. return this.user.update(id, user);
  36. }
  37. remove(id: number) {
  38. return this.user.delete(id);
  39. }
  40. findProfile(id: number) {
  41. return this.user.findOne({
  42. where: {
  43. id,
  44. },
  45. relations: {
  46. profile: true,
  47. },
  48. });
  49. }
  50. findLogsByGroup(id: number) {
  51. return this.logsRepository
  52. .createQueryBuilder('logs')
  53. .select('logs.result', 'result')
  54. .addSelect('COUNT(logs.result)', 'count')
  55. .leftJoinAndSelect('logs.user', 'user')
  56. .where('logs.userId = :id', { id })
  57. .groupBy('logs.result')
  58. .getRawMany();
  59. }
  60. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/661396
推荐阅读
相关标签
  

闽ICP备14008679号