getRawMany()和getMany()的区别

解决SELECT list is not in GROUP BY clause and contains nonaggregated column ‘testdata.logs.id’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

前言:

nest/typeorm报错

SELECT list is not in GROUP BY clause and contains nonaggregated column ‘testdata.logs.id’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

1.返回结果区别

getMany()getRawMany() 返回的结果有一些显著的区别,根据你的具体需求,你可以选择使用其中之一。

1.getMany() 返回的结果:

  1. 返回结果为 TypeORM 实体对象的集合,即经过实体映射(entity mapping)的结果。
  2. 返回的是符合查询条件的实体对象数组,每个元素都是一个经过 TypeORM 映射的实体对象。这意味着你可以直接从结果中访问实体对象的属性,并对其进行操作。
  3. 适用于一般的实体查询及与数据库表对应的操作,例如数据的读取、更新、删除等。

2.getRawMany() 返回的结果:

  1. 返回结果为原始的数据库查询结果,即未经过实体映射的结果。
  2. 返回的是一组普通的 JavaScript 对象数组,每个元素代表了数据库查询结果中的一行记录。这意味着你需要手动处理和操作这些原始的查询结果。
  3. 适用于需要执行原生的 SQL 查询、需要对原始数据进行聚合、统计、复杂数据操作等情况。

总的来说,getMany() 适用于从数据库中获取类型化的实体对象集合进行操作,而 getRawMany() 适用于执行原生的 SQL 查询及对原始数据进行操作

2.看个例子:

在TypeORM中,getRawMany()getMany() 是两种执行查询并返回结果的方法,它们之间有一些关键的区别。

  1. getRawMany() getRawMany() 方法返回的是原始的数据库查询结果,这意味着它返回的是一组普通的 JavaScript 对象,而不是经过实体映射(entity mapping)的 TypeORM 实体对象。这对于复杂的查询或者需要直接操作原始数据的情况非常有用。当你执行原生查询,或者需要聚合函数的结果时,这个方法特别有用。
const result = await entityManager
  .createQueryBuilder()
  .select("user.name", "userName")
  .addSelect("COUNT(*)", "postCount")
  .from(User, "user")
  .leftJoin("user.posts", "post")
  .groupBy("user.id")
  .getRawMany();
  1. getMany() getMany() 方法返回的是经过实体映射(entity mapping)的 TypeORM 实体对象的数组。这意味着返回的结果会被 TypeORM 映射为你定义的实体类的实例。这对于常规的数据库操作和数据持久化非常有用。
const users = await userRepository.find();

总的来说,getRawMany() 适用于需要直接操作原始数据或者复杂查询的情况,而 getMany() 适用于常规的数据库操作和通过实体对象进行处理的情况。

当使用 TypeORM 进行查询时,你可以根据具体的需求来选择使用 getMany()getRawMany()

1.适合使用 getMany() 的情况:

  1. 常规查询:当你希望查询并返回和 TypeORM 实体对象对应的结果时,使用 getMany() 是最直接的方法。比如:

    const users = await userRepository.find();
    
  2. 实体关联查询:当你希望获取实体及其关联的其他实体对象时,如一对多关系中的子实体,或使用 LEFT JOININNER JOIN 查询时,也可以使用 getMany() 来获取实体及其关联的多个实体对象。

    const usersWithPosts = userRepository.find({ relations: ['posts'] });
    

2.适合使用 getRawMany() 的情况:

  1. 原生查询:当你需要执行原生的 SQL 查询,或者使用数据库特定的函数或特性时,通常会选择使用 getRawMany() 来获取原始的查询结果。

    const result = await entityManager
      .createQueryBuilder()
      .select("user.name", "userName")
      .addSelect("COUNT(*)", "postCount")
      .from(User, "user")
      .leftJoin("user.posts", "post")
      .groupBy("user.id")
      .getRawMany();
    
  2. 对于聚合函数的使用:当你需要使用聚合函数(如 COUNT、SUM 等)进行查询时,getRawMany() 可以直接返回原始的聚合结果。

    const postCounts = await postRepository
      .createQueryBuilder()
      .select("COUNT(*)", "postCount")
      .getRawMany();
    

总的来说,当你需要返回实体对象的集合时,使用 getMany();而当需要执行原生的 SQL 查询,或者对原始数据进行操作时,使用 getRawMany()

3.我犯的错

  • 一号查询

     async getLogsList(): Promise<any> {
        return this.logRepository
          .createQueryBuilder('logs')
          .select('logs.response')
          .addSelect('COUNT(logs.response)', 'count')
          .leftJoinAndSelect('logs.user', 'user')
          .where('userId = :id', { id: 2 })
          .groupBy('logs.response')
          .getRawMany(); // 如果你使用原始查询而不是实体的话,使用getRawMany()
      }
    
  • 二号查询

      async getLogsList(): Promise<any> {
        return (
          this.logRepository
          .createQueryBuilder('logs')
          .select('logs.response')
          .addSelect('COUNT(logs.response)', 'count')
          .leftJoinAndSelect('logs.user', 'user')
          .where('userId = :id', { id: 2 })
          .groupBy('logs.response')
          .getMany()
        );
      }
    

二号查询虽然你使用了getMany(),但是查询语句中使用了聚合函数COUNT,这是导致使用 getMany() 出现问题的原因。

getMany() 用于获取实体对象的集合,而 COUNT 是一个聚合函数,它会计算匹配条件的行数,并返回一个单独的结果。在TypeORM中,getMany() 适用于简单的实体查询,但并不适用于需要使用聚合函数的情况。

在二号示例中,,addSelect('COUNT(logs.response)', 'count') 使用了聚合函数来统计logs表中response字段的数量。因此,使用 getMany() 无法正确地返回聚合后的结果。相反,你应该使用 getRawMany() 来获取原始的查询结果,而不是实体对象的集合。

所以,应该使用 .getRawMany() 来获取聚合函数的结果,就像下面这样:

async getLogsList(): Promise<any> {
  return (
    this.logRepository
      .createQueryBuilder('logs')
      .select('logs.response')
      .addSelect('COUNT(logs.response)', 'count')
      .leftJoinAndSelect('logs.user', 'user')
      .where('userId=:id', { id: 2 })
      .groupBy('logs.response')
      .getRawMany()
  );
}

通过使用 .getRawMany(),能够正确地获取到聚合函数的结果,而不是尝试将聚合的结果映射为实体对象的集合。

  • 21
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值