如何在Nest.js中使用TypeOrm

857 阅读3分钟

TypeORM 无疑是 node.js 世界中最成熟的对象关系映射器(ORM )。由于它是用 TypeScript 编写的,所以它在 Nest 框架下运行得非常好

第一步:安装

npm install --save @nestjs/typeorm typeorm mysql2

第二步:在App.module.ts配置

imports: [UserModule, UploadModule, LoginModule,
    TypeOrmModule.forRoot({
      type: "mysql", //数据库类型
      username: "root", //账号
      password: "ling", //密码
      host: "localhost", //host
      port: 3306, //
      database: "ssm", //库名
      // (1)和(2)任选一个配置
      // (1)
      // entities: [__dirname + '/**/*.entity{.ts,.js}'], //实体文件
      synchronize: true, //synchronize字段代表是否自动将实体类同步到数据库
      retryDelay: 500, //重试连接数据库间隔
      retryAttempts: 10,//重试连接数据库的次数
      // (2)
      autoLoadEntities: true, //如果为true,将自动加载实体 forFeature()方法注册的每个实体都将自动添加到配置对象的实体数组中
})],

第三步:编写实体类user.entity.ts

@Column()

import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";

enum demo {
      one = 1,
      two = 2,
      three = 3
}

@Entity()
export class User {
      // 自增
      @PrimaryGeneratedColumn()
      id: Number
      @Column()
      name: string
      @Column()
      // 创建具有生成值的列
      @Generated("uuid")
      uuid: string
      // 将json转字符串存入数据库
      @Column("simple-json")
      json: { one: string; tow: string }
      // 它可以将原始数组值存储在单个字符串列中,所有值都以逗号分隔
      @Column("simple-array")
      array: string[]
      // 枚举类型
      @Column({type: 'enum',enum: demo, default: demo.one})
      enum: number
      // 列选项部分介绍
      @Column({
            type: "varchar",
            name: "ipaaa", //数据库表中的列名
            nullable: true, //在数据库中使列NULL或NOT NULL。 默认情况下,列是nullable:false
            comment: "注释",
            select: true,  //定义在进行查询时是否默认隐藏此列。 设置为false时,列数据不会显示标准查询。 默认情况下,列是select:true
            default: "xxxx", //加数据库级列的DEFAULT值
            primary: false, //将列标记为主要列。 使用方式和@ PrimaryColumn相同。
            update: true, //指示"save"操作是否更新列值。如果为false,则只能在第一次插入对象时编写该值。 默认值为"true"
            collation: "", //定义列排序规则。
      })
      ip: string
}
  1. @Column中可以配置的列选择,附连接
  2. @Column可以支持多种数据类型

第四步:在模块中引入实体类

TypeOrmModule.forFeature()

@Global()
@Module({
  imports:[TypeOrmModule.forFeature([User])],
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule { }

第五步:在提供者进行CURD操作

先声明变量

constructor(@InjectRepository(User) private readonly user: Repository<User>){}

Create(C)

create(createUserDto: CreateUserDto) {
    console.log(createUserDto);
    const data = new User()
    data.id = createUserDto.id
    data.name = createUserDto.name
    data.pwd = createUserDto.pwd
    data.json = createUserDto.json
    data.array = createUserDto.array
    return this.user.save(data);
}

Read(R)

findOne(keyword: string) {
    return this.user.find({
      where:
      {
        name: Like(`%${keyword}%`)
      }
    })
}

Update(U)

update(id: number, updateUserDto: UpdateUserDto) {
    return this.user.update(id, updateUserDto)
}

Delete(D)

remove(id: number) {
    return this.user.delete(id)
}

分页查询

async findAll(query: { keyWord: string, page: number, pageSize: number }) {
    const data = await this.user.find({
      where: {
        name: Like(`%${query.keyWord}%`)
      },
      skip: (query.page - 1) * query.pageSize,
      take: query.pageSize
    })
    const total = await this.user.count({
      where: {
        name: Like(`%${query.keyWord}%`)
      }
    })

    return {
      data,
      total
    }
}

多表关联

设计目的:使每一个用户对应多个标签,属于一个一对多的关系

user实体

image.png

import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { Tags } from "./tags.entity";

@Entity()
export class User {
      // 自增
      @PrimaryGeneratedColumn()
      id: number
      @Column()
      name: string
      @Column()
      pwd: string
      // 将json转字符串存入数据库
      @Column("simple-json")
      json: { one: string; tow: string }
      // 它可以将原始数组值存储在单个字符串列中,所有值都以逗号分隔
      @Column("simple-array")
      array: string[]
      @OneToMany(()=>Tags,(tags)=>tags.user)
      tags: Tags[]
}

tags实体

image.png

import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
import { User } from "./user.entity";

@Entity()
export class Tags {
      @PrimaryGeneratedColumn()
      id: number
      @Column()
      name: string
      @ManyToOne(()=>User)
      user: User
}

service层,插入操作: 先使用findOne()根据id查到user的信息,返回一个User对象;将tags信息先存入tags中,再将user的tags属性进行赋值;最后使用save()保存user信息,会在tags补全userId的信息

async addTags(tags: string[], userId: number) {
  const userInfo = await this.user.findOne({ where: { id: userId } })

  console.log(userInfo);
  
  const tagsList : Tags[] = []
  for (let i in tags) {
    const T = new Tags()
    T.name = tags[i]
    await this.tags.save(T)
    tagsList.push(T)
  }
  userInfo.tags = tagsList
  await this.user.save(userInfo)
  return true
}

service层,查询操作

async findAll1(){
  return this.user.find({relations: ['tags']})
}

第六步:在控制类中调用提供者中的方法

以添加操作为例

@Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.userService.create(createUserDto);
}