QueryBuilder ?
QueryBuilder는 데이터베이스에서 쿼리를 생성하는 데 사용되는 도구나 소프트웨어이다. 이는 일반적으로 데이터베이스에 대한 질의를 구축하고 실행하기 위해 사용된다. 다양한 형식의 데이터베이스에서 사용될 수 있으며, 사용되는 데이터베이스 시스템에 따라 다양한 쿼리 언어와 특정 기능을 지원한다.
주로 QueryBuilder가 하는 일은 개발자나 사용자가 SQL과 같은 쿼리 언어를 직접 작성하지 않고도 시각적이고 직관적인 방식으로 쿼리를 작성할 수 있도록 도와주는 것이다. 이는 대화형 인터페이스나 GUI(그래픽 사용자 인터페이스)를 통해 쿼리를 구성할 수 있는 기능을 제공한다.
QueryBuilder 기능
- 시각적으로 쿼리 작성
- SQL 쿼리를 직접 작성하지 않고도 시각적 요소를 사용하여 조건을 추가하고 조합할 수 있다.
- 데이터베이스 스키마 브라우징
- 데이터베이스의 테이블, 열, 관계 등과 같은 스키마 정보를 표시하고 탐색할 수 있다.
- 쿼리 최적화
- 자동으로 쿼리를 최적화하여 빠른 실행을 도모할 수 있다.
- 다양한 데이터베이스 지원
- 여러 데이터베이스 시스템(MySQL, PostgreSQL, SQLite, 등)에서 쿼리 작성 및 실행을 지원.
- 조인 및 필터링
- 여러 테이블 간의 조인 작업 및 데이터 필터링을 보다 쉽게 수행할 수 있도록 도와줌
이러한 기능을 통해 QueryBuilder는 사용자가 데이터베이스에 대한 복잡한 쿼리를 보다 쉽게 작성하고 실행할 수 있도록 지원함. 이는 개발자들이 생산성을 높이고 오류를 줄이며 데이터베이스 작업을 보다 효율적으로 처리할 수 있도록 돕는 도구이다.
QueryBuilder 예시
const firstUser = await dataSource
.getRepository(User)
.createQueryBuilder("user")
.where("user.id = :id", { id: 1 })
.getOne()
다음과 같은 쿼리를 구축한다.
SELECT
user.id as userId,
user.firstName as userFirstName,
user.lastName as userLastName
FROM users user
WHERE user.id = 1
User의 인스턴스를 반환
User {
id: 1,
firstName: "Timber",
lastName: "Saw"
}
QueryBuilder 중요점
QueryBuilder를 사용할 때 WHERE 표현식에서 고유한 매개변수를 제공해야 함
잘못된 코드
const result = await dataSource
.createQueryBuilder('user')
.leftJoinAndSelect('user.linkedSheep', 'linkedSheep')
.leftJoinAndSelect('user.linkedCow', 'linkedCow')
.where('user.linkedSheep = :id', { id: sheepId })
.andWhere('user.linkedCow = :id', { id: cowId });
작동 코드
const result = await dataSource
.createQueryBuilder('user')
.leftJoinAndSelect('user.linkedSheep', 'linkedSheep')
.leftJoinAndSelect('user.linkedCow', 'linkedCow')
.where('user.linkedSheep = :sheepId', { sheepId })
.andWhere('user.linkedCow = :cowId', { cowId });
=> id가 두번쓰이는게 아니라 :sheepId, :cowId 같이 이름 부여
QueryBuilder 생성법
DataSource 사용
const user = await dataSource
.createQueryBuilder()
.select("user")
.from(User, "user")
.where("user.id = :id", { id: 1 })
.getOne()
entity manager 사용
const user = await dataSource.manager
.createQueryBuilder(User, "user")
.where("user.id = :id", { id: 1 })
.getOne()
repository 사용
const user = await dataSource
.getRepository(User)
.createQueryBuilder("user")
.where("user.id = :id", { id: 1 })
.getOne()
- Query Builder 생성 방법
- 데이터 소스를 이용하거나 entity manager, repository를 통해 Query Builder를 생성할 수 있다. 이를 통해 SELECT, INSERT, UPDATE, DELETE 등 다양한 Query Builder를 생성하고 활용할 수 있다.
- Query Builder의 다양한 유형
- SELECT, INSERT, UPDATE, DELETE, Relation에 따라 다양한 Query Builder가 있으며, 각각의 유형에 따라 적합한 방식으로 쿼리를 구성하고 실행할 수 있다.
- 쿼리 실행 및 결과 가져오기
- getOne, getOneOrFail, getMany, getRawOne, getRawMany 등을 사용하여 데이터베이스로부터 결과를 가져올 수 있으며, Entity나 Raw 데이터 등을 선택하여 가져올 수 있다.
- getOne() - Query Builder로 구성된 쿼리를 실행하고, 해당 쿼리에 딱 하나의 결과만을 반환한다. 결과가 없거나 여러 개의 결과가 있을 경우 오류를 발생시킨다. 일반적으로 단일 결과를 기대하는 쿼리에 사용된다.
- getOneOrFail() - getOne()과 비슷하지만, 결과가 없을 경우 EntityNotFoundError를 발생시킨다. 따라서 단일 결과를 가져와야 하는데 결과가 없는 경우에 오류를 발생시키고자 할 때 사용된다.
- getMany() - Query Builder로 구성된 쿼리를 실행하고, 해당 쿼리에 부합하는 모든 결과를 배열로 반환한다. 여러 개의 결과를 기대하는 쿼리에서 사용된다.
- getRawOne() - Query Builder로 구성된 쿼리를 실행하고, 해당 쿼리의 단일 결과를 반환한다. 그러나 이 결과는 엔티티(Entity)가 아니라 일반적인 JavaScript 객체(raw data)다. 즉, 엔티티 클래스의 인스턴스가 아닌, 직접적으로 데이터베이스로부터 가져온 데이터이다.
- getRawMany() - Query Builder로 구성된 쿼리를 실행하고, 해당 쿼리에 부합하는 모든 결과를 배열로 반환한다. 그러나 여기서도 반환되는 것은 엔티티(Entity)가 아닌 일반적인 JavaScript 객체(raw data)다. 엔티티 클래스의 인스턴스가 아닌 데이터베이스로부터 직접적으로 가져온 데이터를 제공한다.
- 쿼리 작성 기능
- WHERE, HAVING, ORDER BY, GROUP BY, LIMIT, OFFSET, DISTINCT ON 등의 다양한 쿼리 작성 기능을 설명하고 있다. 이를 통해 복잡한 쿼리를 작성하고 실행할 수 있다.
- WHERE - 데이터베이스에서 특정 조건을 만족하는 행을 선택하는데 사용된다. Query Builder에서 where() 메서드를 사용하여 조건을 추가할 수 있다. 예를 들어, where("user.id = :id", { id: 1 })와 같이 사용하여 조건을 지정할 수 있다.
- HAVING - GROUP BY 절을 사용할 때 그룹화된 결과 행을 필터링하는데 사용된다. HAVING 절은 WHERE 절과 유사하지만, 집계 함수와 함께 그룹화된 데이터에 조건을 적용할 때 사용된다.
- ORDER BY - 쿼리의 결과를 정렬하는데 사용된다. orderBy() 메서드를 사용하여 특정 열을 기준으로 오름차순(ASC)이나 내림차순(DESC)으로 정렬할 수 있다. 예를 들어, orderBy("user.id", "DESC")와 같이 사용하여 열을 기준으로 내림차순으로 정렬할 수 있다.
- GROUP BY - 결과 행을 그룹화하는데 사용된다. 특정 열을 기준으로 데이터를 그룹화하여 집계 함수를 사용하거나 그룹별로 결과를 필터링할 때 사용된다.
- LIMIT - 반환되는 결과의 수를 제한하는데 사용된다. 일반적으로 결과 집합의 크기를 제한하여 일부 결과만 가져오는데 사용된다. 예를 들어, limit(10)과 같이 사용하여 최대 10개의 결과만 가져올 수 있다.
- OFFSET - 쿼리에서 반환되는 결과 집합의 시작 위치를 지정하는데 사용된다. 일반적으로 LIMIT와 함께 사용하여 페이지네이션(Pagination)을 구현하는 데 활용된다. 예를 들어, offset(20)과 같이 사용하여 결과의 처음 20개를 건너뛸 수 있다.
- DISTINCT ON - distinctOn(["user.id"]) 메서드는 Postgres 데이터베이스에서 사용되며, 특정 열에 DISTINCT ON 표현을 추가한다. ORDER BY 표현과 함께 사용될 때, DISTINCT ON 표현은 ORDER BY 표현과 왼쪽에서부터 일치해야 한다.
- 예시: createQueryBuilder("user").distinctOn(["user.id"]).orderBy("user.id")
- 이렇게 사용하면 SELECT DISTINCT ON (user.id) ... FROM users user ORDER BY user.id와 같은 SQL 쿼리가 생성된다.
- 파라미터 사용 및 Alias
- 파라미터를 사용하여 데이터를 이스케이프하고 SQL 인젝션을 방지하는 방법과, Alias를 사용하여 SQL 쿼리에서 테이블에 별칭을 지정하는 방법에 대한 설명이 포함되어 있다. Alias는 SELECT 문에서 데이터를 선택하는 데 사용되며, 여러 테이블을 조인하거나 복잡한 쿼리를 작성하는 데 유용하다.
'개발 공부' 카테고리의 다른 글
| Node.js (0) | 2024.07.15 |
|---|---|
| 동기(synchronous) 와 비동기(asynchronous) 함수 (0) | 2024.07.15 |
| TypeORM - QueryBuilder 2 (0) | 2023.11.21 |
| TypeORM (0) | 2023.11.17 |
| REST API와 GraphQL (0) | 2023.11.16 |