NestJS-TypeORM QueryBuilder 常用 SQL 写法

在 NestJS 项目中,this.xxxRepository.createQueryBuilder() 是最常用、最规范的 QueryBuilder 使用方式。

本文以 UserEntity 为例,系统整理 QueryBuilder 对应的常见 SQL 写法 ,所有示例可直接复制使用

一、基础准备

复制代码
@Injectable()
export class UserService {
  constructor(
    @InjectRepository(UserEntity)
    private readonly userRepository: Repository<UserEntity>,
  ) {}
}

以下示例默认写在 UserService 中。

一、新增 & 更新 & 删除

1. INSERT

复制代码
return this.userRepository
  .createQueryBuilder()
  .insert()
  .into(UserEntity)
  .values({
    name: '张三',
    age: 18,
    status: 1,
  })
  .execute();

批量新增

复制代码
return this.userRepository
  .createQueryBuilder()
  .insert()
  .into(UserEntity)
  .values([
    { name: '张三', age: 18 },
    { name: '李四', age: 20 },
  ])
  .execute();

2. UPDATE

复制代码
return this.userRepository
  .createQueryBuilder()
  .update(UserEntity)
  .set({ status: 0 })
  .where('id = :id', { id })
  .execute();

3. DELETE

复制代码
return this.userRepository
  .createQueryBuilder()
  .delete()
  .from(UserEntity)
  .where('id = :id', { id })
  .execute();

二、基础查询(SELECT)

1. 查询单表数据

SQL

复制代码
SELECT * FROM user WHERE status = 1;

QueryBuilder

复制代码
return this.userRepository
  .createQueryBuilder('u')
  .where('u.status = :status', { status: 1 })
  .getMany();

2. 查询指定字段

SQL

复制代码
SELECT id, name FROM user;

return this.userRepository
  .createQueryBuilder('u')
  .select(['u.id', 'u.name'])
  .getMany();

3. 查询单条数据

复制代码
return this.userRepository
  .createQueryBuilder('u')
  .where('u.id = :id', { id })
  .getOne();

三、WHERE 条件用法

1. 多条件 AND / OR

SQL

复制代码
SELECT * FROM user WHERE age > 18 AND status = 1;

return this.userRepository
  .createQueryBuilder('u')
  .where('u.age > :age', { age: 18 })
  .andWhere('u.status = :status', { status: 1 })
  .getMany();

OR

复制代码
.orWhere('u.role = :role', { role: 'admin' })

2. IN 查询

SQL

复制代码
SELECT * FROM user WHERE id IN (1,2,3);

return this.userRepository
  .createQueryBuilder('u')
  .where('u.id IN (:...ids)', { ids: [1, 2, 3] })
  .getMany();

3. LIKE 模糊查询

SQL

复制代码
SELECT * FROM user WHERE name LIKE '%张%';

return this.userRepository
  .createQueryBuilder('u')
  .where('u.name LIKE :name', { name: `%张%` })
  .getMany();

四、排序 & 分页

1. ORDER BY

复制代码
return this.userRepository
  .createQueryBuilder('u')
  .orderBy('u.createTime', 'DESC')
  .getMany();

2. 分页查询

复制代码
return this.userRepository
  .createQueryBuilder('u')
  .skip((page - 1) * pageSize)
  .take(pageSize)
  .getMany();

3. 分页 + 总数

复制代码
return this.userRepository
  .createQueryBuilder('u')
  .skip((page - 1) * pageSize)
  .take(pageSize)
  .getManyAndCount();

五、JOIN 多表查询

1. LEFT JOIN

SQL

复制代码
SELECT * FROM user u
LEFT JOIN order o ON u.id = o.user_id;

return this.userRepository
  .createQueryBuilder('u')
  .leftJoin(OrderEntity, 'o', 'o.userId = u.id')
  .getMany();

2. LEFT JOIN 并返回关联数据

复制代码
return this.userRepository
  .createQueryBuilder('u')
  .leftJoinAndSelect('u.orders', 'o')
  .getMany();

⚠️ 前提:UserEntity 中定义了 @OneToMany(() => OrderEntity, ...)

六、聚合函数(COUNT / SUM)

1. COUNT 查询

复制代码
return this.userRepository
  .createQueryBuilder('u')
  .where('u.status = :status', { status: 1 })
  .getCount();

2. GROUP BY 统计

SQL

复制代码
SELECT status, COUNT(*) total FROM user GROUP BY status;

return this.userRepository
  .createQueryBuilder('u')
  .select('u.status', 'status')
  .addSelect('COUNT(*)', 'total')
  .groupBy('u.status')
  .getRawMany();

3. HAVING

复制代码
return this.userRepository
  .createQueryBuilder('u')
  .select('u.status', 'status')
  .addSelect('COUNT(*)', 'total')
  .groupBy('u.status')
  .having('COUNT(*) > :count', { count: 10 })
  .getRawMany();

七、子查询

1. 子查询 IN

SQL

复制代码
SELECT * FROM user
WHERE id IN (SELECT user_id FROM order WHERE amount > 100);

return this.userRepository
  .createQueryBuilder('u')
  .where(qb => {
    const subQuery = qb
      .subQuery()
      .select('o.userId')
      .from(OrderEntity, 'o')
      .where('o.amount > :amount')
      .getQuery();
    return 'u.id IN ' + subQuery;
  })
  .setParameter('amount', 100)
  .getMany();
相关推荐
桦说编程14 小时前
从 ForkJoinPool 的 Compensate 看并发框架的线程补偿思想
java·后端·源码阅读
躺平大鹅15 小时前
Java面向对象入门(类与对象,新手秒懂)
java
初次攀爬者16 小时前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq
花花无缺16 小时前
搞懂@Autowired 与@Resuorce
java·spring boot·后端
倔强的石头_17 小时前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
Derek_Smart18 小时前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot
NE_STOP19 小时前
MyBatis-mybatis入门与增删改查
java
孟陬1 天前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端
想用offer打牌1 天前
一站式了解四种限流算法
java·后端·go