Drizzle 쿼리 + CRUD

This guide assumes familiarity with:

Drizzle는 데이터베이스 쿼리를 위한 몇 가지 방법을 제공하며, 여러분의 다음 프로젝트에서 어떤 방식을 사용할지 선택할 수 있습니다.
SQL과 유사한 구문을 사용하거나 관계형 구문을 사용할 수 있습니다. 각각의 방법을 살펴보겠습니다.

왜 SQL과 유사한가?


SQL을 안다면, Drizzle도 쉽게 이해할 수 있습니다.

다른 ORM과 데이터 프레임워크는 SQL을 벗어나거나 추상화하는 경향이 있어, SQL과 프레임워크 API를 모두 배워야 하는 이중 학습 곡선이 생깁니다.

Drizzle은 반대입니다. 우리는 SQL을 받아들이고 Drizzle을 SQL과 유사하게 설계했습니다. 따라서 학습 곡선이 거의 없으며, SQL의 모든 기능을 활용할 수 있습니다.

// 데이터에 접근
await db
  .select()
	.from(posts)
	.leftJoin(comments, eq(posts.id, comments.post_id))
	.where(eq(posts.id, 10))
SELECT * 
FROM posts
LEFT JOIN comments ON posts.id = comments.post_id
WHERE posts.id = 10

SQL과 유사한 구문을 사용하면, 순수 SQL로 할 수 있는 대부분의 작업을 똑같이 수행할 수 있습니다. 또한 Drizzle이 어떤 쿼리를 생성할지 정확히 알 수 있습니다. SELECT, INSERT, UPDATE, DELETE와 같은 다양한 쿼리를 수행할 수 있으며, 별칭(aliases), WITH 절, 서브쿼리, 준비된 문장(prepared statements) 등을 사용할 수 있습니다. 더 많은 예제를 살펴보겠습니다.

insert
update
delete
await db.insert(users).values({ email: 'user@gmail.com' })
INSERT INTO users (email) VALUES ('user@gmail.com')

SQL과 비슷한 방식이 아닌 이유는?

우리는 항상 완벽하게 균형 잡힌 해결책을 추구합니다. SQL과 비슷한 쿼리 방식이 모든 요구사항을 100% 충족할 수 있지만, 특정 일반적인 시나리오에서는 데이터를 더 효율적으로 조회할 수 있습니다.

Drizzle은 여러분이 조인이나 데이터 매핑에 대해 걱정하지 않고도 데이터베이스에서 관계형 및 중첩된 데이터를 가장 편리하고 성능 좋은 방식으로 가져올 수 있도록 Queries API를 구축했습니다.

Drizzle은 항상 정확히 하나의 SQL 쿼리를 출력합니다. 서버리스 데이터베이스와 함께 사용해도 성능이나 왕복 비용에 대해 걱정할 필요가 없습니다!

const result = await db.query.users.findMany({
	with: {
		posts: true
	},
});

고급 기능

Drizzle을 사용하면 쿼리를 원하는 방식으로 합성하고 분할할 수 있습니다. 메인 쿼리와 독립적으로 필터를 구성하거나, 서브쿼리나 조건문을 분리하는 등 다양한 작업이 가능합니다. 몇 가지 고급 예제를 살펴보겠습니다.

WHERE 문을 구성한 후 쿼리에서 사용하기

async function getProductsBy({
  name,
  category,
  maxPrice,
}: {
  name?: string;
  category?: string;
  maxPrice?: string;
}) {
  const filters: SQL[] = [];

  if (name) filters.push(ilike(products.name, name));
  if (category) filters.push(eq(products.category, category));
  if (maxPrice) filters.push(lte(products.price, maxPrice));

  return db
    .select()
    .from(products)
    .where(and(...filters));
}

서브쿼리를 별도의 변수로 분리한 후 메인 쿼리에서 사용하기

const subquery = db
	.select()
	.from(internalStaff)
	.leftJoin(customUser, eq(internalStaff.userId, customUser.id))
	.as('internal_staff');

const mainQuery = await db
	.select()
	.from(ticket)
	.leftJoin(subquery, eq(subquery.internal_staff.userId, ticket.staffId));

다음 단계는?