Nest typeorm作分页查询(总条数、总页数、当前页、每页条数、模糊搜索、非空判断、联表查询)

文章介绍了如何在TypeORM中进行基本的数据库操作,包括使用@Query和ParseIntPipe处理HTTP查询参数,实现分页查询(.skip和.take),模糊查询(LIKE操作配合Brackets处理非空情况),以及多对多关系的联表查询和角色字段的模糊搜索。示例代码展示了Service层的方法,用于获取带有分页、过滤条件的用户列表,同时计算总条数。

需求

基本的表格操作,包括表的分页、模糊查询、联表查询、总数统计等。

一、Controller层

传入当前页,每页查询的条数,用户列表的username 和 nickname字段 和角色列表的role字段,通过@Query()解构值,通过管道将类型转换为Int(number)型。

  @Get('list')
  getAllUser( @Query('current', ParseIntPipe) current,
    @Query('size', ParseIntPipe) size,
    @Query('username') username,
    @Query('nickname') nickname,
    @Query('role') role) {
    return this.userService.findAll(current,size, username, nickname,role);
  }

二、Service层

  • 分页简介:

.take(10)

返回前 10 条数据

.skip(10)

除前10条以外的所有数据

两者想互搭配即可作分页,假设每页数据固定展示10条,现想查询第二页的数据(11-20),故查询语句应为:

.skip(10)
.take(10)
  • 模糊查询和非空查询

现需要对Controller层传入的username进行模糊搜索和非空处理,若传入字段为空,则不进行模糊匹配,非空判断需引入Brackets(typeorm中引入)

使用Brackets将复杂的WHERE表达式添加到现有的WHERE

.where(
        new Brackets((qb) => {
          // 值不为空,进行模糊搜索
          if (username) {
            return qb.where('user.username LIKE :username', {
              username: `%${username}%`,
            });
          } else {
            return qb;
          }
        }),
      )
  • 多对多联表查询,并对角色字段进行模糊搜索和非空判断。

User 实体类:

@ManyToMany((type) => Role, (role) => role.users)
  roles: Role[];

Role:

  @Column({ length: 500, comment: '角色名称' })
  name: string;
  @ManyToMany(() => User, (user) => user.roles)
  @JoinTable()
  users: User[];

Service层代码
如果你不需要所有字段,使用leftJoin 和 addSelect更优。

  • leftJoinAndSelect 会返回关联表中的所有字段

  • leftJoin 和 addSelect查询部分字段

 .leftJoinAndSelect('user.roles', 'role')
 //.leftJoin('user.roles', 'role')
 //.addSelect(['role.id', 'role.roleName'])
 .where(
        new Brackets((qb) => {
          if (role) {
            return qb.andWhere('role.name LIKE :role', {
              role: `%${role}%`,
            });
          } else {
            return qb;
          }
        }),
      )

全部代码:

// 获取全部用户
  async findAll(
    current: number,
    size: number,
    username: string,
    nickname: string,
    role: string,
  ) {
    // 查询表的总条数
    // 此处优化了下,开始使用的 leftJoinAndSelect 会返回关联表中的所有字段,故使用 leftJoin 和 addSelect查询部分字段
    // 查询总数据和总条数使用 getManyAndCount

    let list = await this.userRepository
      .createQueryBuilder('user')
      // .leftJoinAndSelect('user.roles', 'role')
      .leftJoin('user.roles', 'role')
      .addSelect(['role.id', 'role.roleName'])
      .where('user.isDelete = :isDelete ', { isDelete: 0 })
      .andWhere(
        new Brackets((qb) => {
          if (username) {
            return qb.where('user.username LIKE :username', {
              username: `%${username}%`,
            });
          } else {
            return qb;
          }
        }),
      )
      .andWhere(
        new Brackets((qb) => {
          if (nickname) {
            return qb.andWhere('user.nickname LIKE :nickname', {
              nickname: `%${nickname}%`,
            });
          } else {
            return qb;
          }
        }),
      )
      .andWhere(
        new Brackets((qb) => {
          if (role) {
            return qb.andWhere('role.id LIKE :role', {
              role: `%${role}%`,
            });
          } else {
            return qb;
          }
        }),
      )
      .skip((current - 1) * size)
      .take(size)
      .getManyAndCount();

    return {
      list: list[0],
      total: list[1],
      size,
      current,
      pages:Math.ceil(list[1] / size),
    };
  }

此处查询总条数使用getManyAndCount()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值