sql<T>๋ ๋ฐํ์ ๋งคํ์ ์ํํ์ง ์์ต๋๋ค. sql<T>๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ํ๋ ํ์
์ ์์ ํ Drizzle์ ์ํ ํฌํผ์
๋๋ค. SQL ์ฟผ๋ฆฌ๋ ๋งค์ฐ ๋ค์ํ๊ณ ์ฌ์ฉ์ ์ ์๊ฐ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ์ ํํ ํ์
์ ๋์ ์ผ๋ก ๊ฒฐ์ ํ ์ ์๋ ์คํ ๊ฐ๋ฅํ ๋ฐฉ๋ฒ์ด ์๋ค๋ ์ ์ ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
๋ง๋ฒ์ sql ์ฐ์ฐ์ ๐ช
ORM ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์์ ํ ๋, ์ ๊ณต๋๋ ORM ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ ํน์ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๊ธฐ ์ด๋ ค์ด ๊ฒฝ์ฐ๊ฐ ์์ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ํฉ์์๋ ์์ ๋ฌธ์์ด๋ก ์ฟผ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๋ raw ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ raw ์ฟผ๋ฆฌ๋ ํ์ ์์ ์ฑ๊ณผ ์ฟผ๋ฆฌ ๋งค๊ฐ๋ณ์ํ์ ์ด์ ์ด ๋ถ์กฑํ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ง์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ sql ํ
ํ๋ฆฟ ๊ฐ๋
์ ๋์
ํ์ต๋๋ค. ์ด ํ
ํ๋ฆฟ์ ์ฌ์ฉํ๋ฉด ๋์ฑ ํ์
์์ ํ๊ณ ๋งค๊ฐ๋ณ์ํ๋ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ ์ ์์ด ์ฝ๋์ ์ ๋ฐ์ ์ธ ์์ ์ฑ๊ณผ ์ ์ฐ์ฑ์ด ํฅ์๋ฉ๋๋ค. ๊ฐ๋ ฅํ ORM ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ Drizzle๋ sql ํ
ํ๋ฆฟ์ ์ง์ํฉ๋๋ค.
Drizzle์ sql ํ
ํ๋ฆฟ์ ์ฌ์ฉํ๋ฉด ์ฟผ๋ฆฌ ์์ฑ์ ์์ด ๋ ๋์๊ฐ ์ ์์ต๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฟผ๋ฆฌ ๋น๋๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ฒด ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ ๋ฐ ์ด๋ ค์์ด ์๋ ๊ฒฝ์ฐ, Drizzle ์ฟผ๋ฆฌ์ ํน์ ์น์
๋ด์์ sql ํ
ํ๋ฆฟ์ ์ ํ์ ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ ์ฐ์ฑ์ ํตํด ๋ถ๋ถ SELECT ๋ฌธ, WHERE ์ , ORDER BY ์ , HAVING ์ , GROUP BY ์ , ๊ทธ๋ฆฌ๊ณ ๊ด๊ณํ ์ฟผ๋ฆฌ ๋น๋์์๋ sql ํ
ํ๋ฆฟ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
Drizzle์์ sql ํ ํ๋ฆฟ์ ๊ธฐ๋ฅ์ ํ์ฉํ๋ฉด ์ํ๋ ์ฟผ๋ฆฌ ๊ตฌ์กฐ์ ๋ณต์ก์ฑ์ ๋ฌ์ฑํ๋ฉด์๋ ํ์ ์์ ์ฑ๊ณผ ์ฟผ๋ฆฌ ๋งค๊ฐ๋ณ์ํ์ ์ฅ์ ์ ์ ์งํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ ํ๋ฆฌ์ผ์ด์ ๋ด์์ ๋์ฑ ๊ฒฌ๊ณ ํ๊ณ ์ ์ง ๊ด๋ฆฌ๊ฐ ์ฉ์ดํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
sqlโ ํ ํ๋ฆฟ
๋ค๋ฅธ ORM์์๋ ํํ ์ ํ ์ ์๋ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ๋ฒ ์ค ํ๋๋ raw ์ฟผ๋ฆฌ๋ฅผ ์ํด sql ์ฟผ๋ฆฌ๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์
๋๋ค.
import { sql } from 'drizzle-orm'
const id = 69;
await db.execute(sql`select * from ${usersTable} where ${usersTable.id} = ${id}`)๋ค์๊ณผ ๊ฐ์ ์ฟผ๋ฆฌ๊ฐ ์์ฑ๋ฉ๋๋ค
select * from "users" where "users"."id" = $1; --> [69]sql ๋งค๊ฐ๋ณ์์ ์ ๊ณต๋ ๋ชจ๋ ํ ์ด๋ธ๊ณผ ์ปฌ๋ผ์ ์๋์ผ๋ก ํด๋น SQL ๊ตฌ๋ฌธ์ ๋งคํ๋๋ฉฐ, ํ ์ด๋ธ์ ๋ํด์๋ ์ด์ค์ผ์ดํ๋ ์ด๋ฆ์ด ์ฌ์ฉ๋๊ณ , ์ด์ค์ผ์ดํ๋ ํ ์ด๋ธ ์ด๋ฆ์ด ์ปฌ๋ผ ์ด๋ฆ์ ์ถ๊ฐ๋ฉ๋๋ค.
๋ํ ${id}์ ๊ฐ์ ๋์ ๋งค๊ฐ๋ณ์๋ $1 ํ๋ ์ด์คํ๋๋ก ๋งคํ๋๋ฉฐ, ํด๋น ๊ฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ณ๋๋ก ์ ๋ฌ๋๋ ๊ฐ ๋ฐฐ์ด๋ก ์ด๋๋ฉ๋๋ค.
์ด๋ฌํ ์ ๊ทผ ๋ฐฉ์์ ์ ์ฌ์ ์ธ SQL ์ธ์ ์ ์ทจ์ฝ์ ์ ํจ๊ณผ์ ์ผ๋ก ๋ฐฉ์งํฉ๋๋ค.
sql<T>
unknown ์ด์ธ์ ํน์ ํ์
์ด ํ์ํ ํ๋์์ ์ฌ์ฉํ ์ ์๋๋ก Drizzle์์ ์ปค์คํ
ํ์
์ ์ ์ํ ์ ์์ต๋๋ค.
์ด ๊ธฐ๋ฅ์ ๋ถ๋ถ select ์ฟผ๋ฆฌ์์ ํนํ ์ ์ฉํ๋ฉฐ, ์ ํ๋ ํ๋์ ๋ํ ์ผ๊ด๋ ํ์ดํ์ ๋ณด์ฅํฉ๋๋ค:
// sql<T> ํ์
์ด ์ ์๋์ง ์์ ๊ฒฝ์ฐ
const response: { lowerName: unknown }[] = await db.select({
lowerName: sql`lower(${usersTable.id})`
}).from(usersTable);
// sql<T> ํ์
์ด ์ ์๋ ๊ฒฝ์ฐ
const response: { lowerName: string }[] = await db.select({
lowerName: sql<string>`lower(${usersTable.id})`
}).from(usersTable);sql``.mapWith()
๋ฐ์ดํฐ๋ฒ ์ด์ค ๋๋ผ์ด๋ฒ์์ drizzle๋ก ์ ๋ฌ๋๋ ๊ฐ์ ๋ํ ๋ฐํ์ ๋งคํ์ด ํ์ํ ๊ฒฝ์ฐ .mapWith()๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ด ํจ์๋ ๋ฐํ์์ ์๋ต์ ๋งคํํ ๋ค์ํ ๊ฐ์ ๋ฐ์ต๋๋ค.
mapWith ๋ด๋ถ์ ์ธํฐํ์ด์ค๊ฐ Column์ ์ํด ๊ตฌํ๋ ์ธํฐํ์ด์ค์ ๋์ผํ ํ, ํน์ ์ปฌ๋ผ ๋งคํ ์ ๋ต์ ๋ณต์ ํ ์ ์์ต๋๋ค.
const usersTable = pgTable('users', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
});
// ๋ฐํ์์ ์ด ๊ฐ๋ค์ drizzle์์ `text` ์ปฌ๋ผ์ด ๋งคํ๋๋ ๊ฒ๊ณผ ๋์ผํ๊ฒ ๋งคํ๋ฉ๋๋ค
sql`...`.mapWith(usersTable.name);DriverValueDecoder ์ธํฐํ์ด์ค์ ๋ํ ์์ฒด ๊ตฌํ์ ์ ๋ฌํ ์๋ ์์ต๋๋ค:
sql``.mapWith({
mapFromDriverValue: (value: any) => {
const mappedValue = value;
// ์ ์ฉํ๋ ค๋ ๋งคํ
return mappedValue;
},
});
// ๋๋
sql``.mapWith(Number);sql``.as<T>()
๋ค์ํ ๊ฒฝ์ฐ์ ์ฌ์ฉํ๋ ค๋ ์ปค์คํ ํ๋์ ์ด๋ฆ์ ์ง์ ํ๋ ๋ฐฉ๋ฒ์ ๊ฒฐ์ ํ๊ธฐ๊ฐ ์ด๋ ค์ธ ์ ์์ต๋๋ค. ์ ํ๋ ํ๋์ ๋ํด ๋ณ์นญ์ ๋ช ์์ ์ผ๋ก ์ง์ ํด์ผ ํ๋ ์ํฉ์ด ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด๋ ๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ๋ค๋ฃฐ ๋ ํนํ ์ ์ฉํ ์ ์์ต๋๋ค.
์ด๋ฌํ ์๋๋ฆฌ์ค๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ณ์นญ์ ๋ช
์์ ์ผ๋ก ์ ์ํ ์ ์๋ ์ ์ฉํ .as('alias_name') ํฌํผ๋ฅผ ๋์
ํ์ต๋๋ค. ์ด ๊ธฐ๋ฅ์ ํ์ฉํ๋ฉด ํ๋์ ๋ํด ๋ช
ํํ๊ณ ์๋ฏธ ์๋ ์ด๋ฆ์ ์ ๊ณตํ์ฌ ์ฟผ๋ฆฌ๋ฅผ ๋์ฑ ์ง๊ด์ ์ด๊ณ ์ฝ๊ธฐ ์ฝ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค.
sql`lower(usersTable.name)`.as('lower_name')... "usersTable"."name" as lower_name ...sql.raw()
์
๋ ฅ์์ ๋งค๊ฐ๋ณ์ํ๋ ๊ฐ์ ์์ฑํ๊ฑฐ๋ ํ
์ด๋ธ/์ปฌ๋ผ์ ์ด์ค์ผ์ดํ๋ ๊ฒ์ผ๋ก ๋งคํํ ํ์๊ฐ ์๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ๋์ ์ฟผ๋ฆฌ๋ฅผ ๊ทธ๋๋ก ์์ฑํ๊ณ ์ถ์ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ํฉ์ ์ํด sql.raw() ํจ์๋ฅผ ์ ๊ณตํฉ๋๋ค.
sql.raw() ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ์ถ๊ฐ์ ์ธ ์ฒ๋ฆฌ๋ ์ด์ค์ผ์ดํ ์์ด ์ฟผ๋ฆฌ ๋ด์ raw SQL ๋ฌธ์ ํฌํจํ ์ ์์ต๋๋ค. ์ด๋ ์ฌ์ ์ ๊ตฌ์ฑ๋ SQL ๋ฌธ์ด ์๊ฑฐ๋ ๋ณต์กํ๊ฑฐ๋ ๋์ ์ธ SQL ์ฝ๋๋ฅผ ์ฟผ๋ฆฌ์ ์ง์ ํตํฉํด์ผ ํ ๋ ์ ์ฉํ ์ ์์ต๋๋ค.
sql.raw(`select * from users where id = ${12}`);
// vs
sql`select * from users where id = ${12}`;select * from users where id = 12;
--> vs
select * from users where id = $1; --> [12]sql ํจ์ ๋ด์์ sql.raw()๋ฅผ ์ฌ์ฉํ์ฌ ๋ฉ์ธ sql ํ
ํ๋ฆฟ ํจ์๋ฅผ ํตํด ์ด์ค์ผ์ดํํ์ง ์๊ณ raw ๋ฌธ์์ด์ ํฌํจํ ์๋ ์์ต๋๋ค.
sql ํจ์ ๋ด์์ sql.raw()๋ฅผ ์ฌ์ฉํ๋ฉด ์ด์ค์ผ์ดํ๋์ง ์์ raw ๋ฌธ์์ด์ ์ฟผ๋ฆฌ์ ์ง์ ํตํฉํ ์ ์์ต๋๋ค. ์ด๋ ํ
ํ๋ฆฟ ํจ์์ ์๋ ์ด์ค์ผ์ดํ๋ ์์ ์ ์ํฅ์ ๋ฐ์ง ์์์ผ ํ๋ ํน์ SQL ์ฝ๋๋ ํํ์์ด ์์ ๋ ํนํ ์ ์ฉํ ์ ์์ต๋๋ค.
sql`select * from ${usersTable} where id = ${12}`;
// vs
sql`select * from ${usersTable} where id = ${sql.raw(12)}`;select * from "users" where id = $1; --> [12]
--> vs
select * from "users" where id = 12;sql.fromList()
sql ํ
ํ๋ฆฟ์ SQL ๋ถ๋ถ์ ๋ฐฐ์ด์ธ sql ์ฒญํฌ๋ฅผ ์์ฑํ๋ฉฐ, ์ด๋ Drizzle์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ฟผ๋ฆฌ์ SQL์ ์ ์ฉํ ํ ์ฟผ๋ฆฌ์ ๋งค๊ฐ๋ณ์๋ก ์ฐ๊ฒฐ๋ฉ๋๋ค.
ํน์ ์๋๋ฆฌ์ค์์๋ ์ปค์คํ ๋น์ฆ๋์ค ๋ก์ง์ ์ฌ์ฉํ์ฌ ์ด๋ฌํ ์ฒญํฌ๋ฅผ ๋ฐฐ์ด๋ก ์ง๊ณํ ๋ค์, ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ฟผ๋ฆฌ์ ์ ๋ฌํ ์ ์๋ ๋จ์ผ SQL ๋ฌธ์ผ๋ก ์ฐ๊ฒฐํด์ผ ํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ fromList ํจ์๊ฐ ๋งค์ฐ ์ ์ฉํ ์ ์์ต๋๋ค.
fromList ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ SQL ์ฒญํฌ๋ฅผ ๋จ์ผ SQL ๋ฌธ์ผ๋ก ๊ฒฐํฉํ ์ ์์ต๋๋ค. ํน์ ์๊ตฌ ์ฌํญ์ ๋ฐ๋ผ ๊ฐ๋ณ SQL ๋ถ๋ถ์ ์ง๊ณํ๊ณ ์ฐ๊ฒฐํ ๋ค์ ์คํํ ์ ์๋ ํตํฉ๋ SQL ์ฟผ๋ฆฌ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
const sqlChunks: SQL[] = [];
sqlChunks.push(sql`select * from users`);
// ์ผ๋ถ ๋ก์ง
sqlChunks.push(sql` where `);
// ์ผ๋ถ ๋ก์ง
for (let i = 0; i < 5; i++) {
sqlChunks.push(sql`id = ${i}`);
if (i === 4) continue;
sqlChunks.push(sql` or `);
}
const finalSql: SQL = sql.fromList(sqlChunks)select * from users where id = $1 or id = $2 or id = $3 or id = $4 or id = $5; --> [0, 1, 2, 3, 4]sql.join()
์ค์ ๋ก sql.join ํจ์๋ fromList ํฌํผ์ ์ ์ฌํ ๋ชฉ์ ์ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋ฌ๋ SQL ์ฒญํฌ ์ฌ์ด์ ๊ณต๋ฐฑ์ ์ฒ๋ฆฌํ๊ฑฐ๋ SQL ์ฒญํฌ๋ฅผ ์ฐ๊ฒฐํ๊ธฐ ์ํ ์ปค์คํ
๊ตฌ๋ถ์๋ฅผ ์ง์ ํ ๋ ์ถ๊ฐ์ ์ธ ์ ์ฐ์ฑ์ ์ ๊ณตํฉ๋๋ค.
sql.join์ ์ฌ์ฉํ๋ฉด ์ง์ ๋ ๊ตฌ๋ถ์๋ฅผ ์ฌ์ฉํ์ฌ SQL ์ฒญํฌ๋ฅผ ํจ๊ป ์ฐ๊ฒฐํ ์ ์์ต๋๋ค. ์ด ๊ตฌ๋ถ์๋ ์ฒญํฌ ์ฌ์ด์ ์ฝ์
ํ๋ ค๋ ๋ชจ๋ ๋ฌธ์์ด์ด๋ ๋ฌธ์๊ฐ ๋ ์ ์์ต๋๋ค.
์ด๋ SQL ์ฒญํฌ์ ํ์ ์ง์ ์ด๋ ๊ตฌ๋ถ์ ๋ํ ํน์ ์๊ตฌ ์ฌํญ์ด ์์ ๋ ํนํ ์ ์ฉํฉ๋๋ค. ์ปค์คํ ๊ตฌ๋ถ์๋ฅผ ์ง์ ํ๋ฉด ์ต์ข SQL ์ฟผ๋ฆฌ์์ ์ํ๋ ๊ตฌ์กฐ์ ํ์์ ๋ฌ์ฑํ ์ ์์ต๋๋ค.
const sqlChunks: SQL[] = [];
sqlChunks.push(sql`select * from users`);
// ์ผ๋ถ ๋ก์ง
sqlChunks.push(sql`where`);
// ์ผ๋ถ ๋ก์ง
for (let i = 0; i < 5; i++) {
sqlChunks.push(sql`id = ${i}`);
if (i === 4) continue;
sqlChunks.push(sql`or`);
}
const finalSql: SQL = sql.join(sqlChunks, sql.raw(' '));select * from users where id = $1 or id = $2 or id = $3 or id = $4 or id = $5; --> [0, 1, 2, 3, 4]sql.append()
sql ํ
ํ๋ฆฟ์ ์ฌ์ฉํ์ฌ ์ด๋ฏธ SQL์ ์์ฑํ ๊ฒฝ์ฐ, append ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์์ฑ๋ SQL์ ์ง์ ์ ์ฒญํฌ๋ฅผ ์ถ๊ฐํจ์ผ๋ก์จ fromList์ ๋์ผํ ๋์์ ๋ฌ์ฑํ ์ ์์ต๋๋ค.
append ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๊ธฐ์กด SQL ๋ฌธ์์ด์ ์ถ๊ฐ SQL ์ฒญํฌ๋ฅผ ๋์ ์ผ๋ก ์ถ๊ฐํ์ฌ ํจ๊ณผ์ ์ผ๋ก ํจ๊ป ์ฐ๊ฒฐํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ฒญํฌ๋ฅผ ์ต์ข SQL ์ฟผ๋ฆฌ๋ก ์ง๊ณํ๊ธฐ ์ํ ์ปค์คํ ๋ก์ง์ด๋ ๋น์ฆ๋์ค ๊ท์น์ ํตํฉํ ์ ์์ต๋๋ค.
const finalSql = sql`select * from users`;
// ์ผ๋ถ ๋ก์ง
finalSql.append(sql` where `);
// ์ผ๋ถ ๋ก์ง
for (let i = 0; i < 5; i++) {
finalSql.append(sql`id = ${i}`);
if (i === 4) continue;
finalSql.append(sql` or `);
}select * from users where id = $1 or id = $2 or id = $3 or id = $4 or id = $5; --> [0, 1, 2, 3, 4]sql.empty()
sql.empty()๋ฅผ ์ฌ์ฉํ๋ฉด ๋น SQL ๊ฐ์ฒด๋ก ์์ํ ๋ค์ ํ์์ ๋ฐ๋ผ SQL ์ฒญํฌ๋ฅผ ๋์ ์ผ๋ก ์ถ๊ฐํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ปค์คํ ๋ก์ง์ด๋ ์กฐ๊ฑด์ ์ ์ฉํ์ฌ ๊ฐ ์ฒญํฌ์ ๋ด์ฉ์ ๊ฒฐ์ ํ๋ฉด์ SQL ์ฟผ๋ฆฌ๋ฅผ ์ ์ง์ ์ผ๋ก ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
sql.empty()๋ฅผ ์ฌ์ฉํ์ฌ SQL ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํํ ํ์๋ ๋งค๊ฐ๋ณ์ํ, ๊ตฌ์ฑ, ์ด์ค์ผ์ดํ์ ๊ฐ์ sql ํ ํ๋ฆฟ์ ์ ์ฒด ๊ธฐ๋ฅ์ ํ์ฉํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ํน์ ์๊ตฌ ์ฌํญ์ ๋ง๊ฒ ์ ์ฐํ๊ณ ํต์ ๋ ๋ฐฉ์์ผ๋ก SQL ์ฟผ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
const finalSql = sql.empty();
// ์ผ๋ถ ๋ก์ง
finalSql.append(sql`select * from users`);
// ์ผ๋ถ ๋ก์ง
finalSql.append(sql` where `);
// ์ผ๋ถ ๋ก์ง
for (let i = 0; i < 5; i++) {
finalSql.append(sql`id = ${i}`);
if (i === 4) continue;
finalSql.append(sql` or `);
}select * from users where id = $1 or id = $2 or id = $3 or id = $4 or id = $5; --> [0, 1, 2, 3, 4]sql์ ๋ฌธ์์ด๊ณผ ๋งค๊ฐ๋ณ์๋ก ๋ณํํ๊ธฐ
์์ ๋ชจ๋ ์์ ์์ TypeScript์ SQL ํ ํ๋ฆฟ ๊ตฌ๋ฌธ ์ฌ์ฉ๊ณผ ์์ฑ๋ SQL ์ถ๋ ฅ์ ๊ด์ฐฐํ์ต๋๋ค.
SQL ํ ํ๋ฆฟ์์ ์์ฑ๋ ์ฟผ๋ฆฌ ๋ฌธ์์ด๊ณผ ํด๋น ๋งค๊ฐ๋ณ์๋ฅผ ์ป์ผ๋ ค๋ฉด, ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ ค๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐฉ์ธ์ ์ง์ ํด์ผ ํฉ๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ง๋ค ๋งค๊ฐ๋ณ์ํ ๋ฐ ์ด์ค์ผ์ดํ์ ๋ํ ๊ตฌ๋ฌธ์ด ๋ค๋ฅด๋ฏ๋ก ์ ์ ํ ๋ฐฉ์ธ์ ์ ํํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
๋ฐฉ์ธ์ ์ ํํ ํ์๋ ํด๋น ๊ตฌํ์ ๊ธฐ๋ฅ์ ํ์ฉํ์ฌ SQL ํ ํ๋ฆฟ์ ์ํ๋ ์ฟผ๋ฆฌ ๋ฌธ์์ด๊ณผ ๋งค๊ฐ๋ณ์ ํ์์ผ๋ก ๋ณํํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์์ ์ค์ธ ํน์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์คํ ๊ณผ์ ํธํ์ฑ์ด ๋ณด์ฅ๋ฉ๋๋ค.
import { PgDialect } from 'drizzle-orm/pg-core';
const pgDialect = new PgDialect();
pgDialect.sqlToQuery(sql`select * from ${usersTable} where ${usersTable.id} = ${12}`);select * from "users" where "users"."id" = $1; --> [ 12 ]select์์ sql ์ฌ์ฉํ๊ธฐ
๋ถ๋ถ select ์ฟผ๋ฆฌ์์๋ sql ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ถ๋ถ select ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉด ์ ์ฒด ํ์ ๊ฐ์ ธ์ค๋ ๋์ ํ ์ด๋ธ์์ ํน์ ํ๋๋ ์ปฌ๋ผ์ ๊ฒ์ํ ์ ์์ต๋๋ค.
๋ถ๋ถ select ์ฟผ๋ฆฌ์ ๋ํ ๋ ์์ธํ ์ ๋ณด๋ **Core API ๋ฌธ์**์์ ํ์ธํ ์ ์์ต๋๋ค.
ํ ์ด๋ธ์์ ๋ค์ํ ์ปค์คํ ํ๋ ์ ํํ๊ธฐ
์ฌ๊ธฐ์ sql<T>, sql``.mapWith(), **sql``.as<T>()**์ ์ฌ์ฉ๋ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
import { sql } from 'drizzle-orm'
import { usersTable } from 'schema'
await db.select({
id: usersTable.id,
lowerName: sql<string>`lower(${usersTable.name})`,
aliasedName: sql<string>`lower(${usersTable.name})`.as('aliased_column'),
count: sql<number>`count(*)`.mapWith(Number)
}).from(usersTable)select `id`, lower(`name`), lower(`name`) as `aliased_column`, count(*) from `users`;where์์ sql ์ฌ์ฉํ๊ธฐ
์ค์ ๋ก Drizzle์ sql ํ ํ๋ฆฟ ๋ด์์ ์ฌ์ฉํ ์ ์๋ ์ฌ๋ฌ ํํ์์ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ํ์ฅ ๊ธฐ๋ฅ์ด๋ ๋ค๋ฅธ ์๋จ์ ํตํด ์ ๊ณต๋๋ ํํ์์ ํฌํจํ์ฌ ๋ ๊ด๋ฒ์ํ ํํ์์ ์ฌ์ฉํ ์ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ ๊ฒ์ด ์ฌ์ค์ ๋๋ค.
์ ์ฐ์ฑ์ ๋ณด์ฅํ๊ณ Drizzle์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์ํ์ง ์๋ ํํ์์ ์ฌ์ฉํ ์ ์๋๋ก ํ๊ธฐ ์ํด, sql ํจ์๋ฅผ ์ฌ์ฉํ์ฌ SQL ํ ํ๋ฆฟ์ ์ง์ ์์ฑํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด SQL์ ๋ชจ๋ ๊ธฐ๋ฅ์ ํ์ฉํ๊ณ ๋์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํนํ๋ ํํ์์ด๋ ๊ธฐ๋ฅ์ ํตํฉํ ์ ์์ต๋๋ค.
sql ํ ํ๋ฆฟ์ ์ฌ์ฉํ๋ฉด Drizzle์ ์ฌ์ ์ ์๋ ํํ์์๋ง ์ ํ๋์ง ์์ต๋๋ค. ๋์ ๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ํํํ๊ณ ๊ธฐ๋ณธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์คํ ์ด ์ ๊ณตํ๋ ์ง์๋๋ ํํ์์ ํตํฉํ ์ ์์ต๋๋ค.
sql์ ์ฌ์ฉํ id๋ก ํํฐ๋งํ๊ธฐ
import { sql } from 'drizzle-orm'
import { usersTable } from 'schema'
const id = 77
await db.select()
.from(usersTable)
.where(sql`${usersTable.id} = ${id}`)select * from "users" where "users"."id" = $1; --> [ 77 ]๊ณ ๊ธ ์ ์ฒด ํ ์คํธ ๊ฒ์ where ๋ฌธ
import { sql } from 'drizzle-orm'
import { usersTable } from 'schema'
const searchParam = "Ale"
await db.select()
.from(usersTable)
.where(sql`to_tsvector('simple', ${usersTable.name}) @@ to_tsquery('simple', ${searchParam})`)select * from "users" where to_tsvector('simple', "users"."name") @@ to_tsquery('simple', '$1'); --> [ "Ale" ]orderBy์์ sql ์ฌ์ฉํ๊ธฐ
Drizzle์์ ์ฌ์ฉํ ์ ์๋ ์ ๋ ฌ์ ์ํ ํน์ ๊ธฐ๋ฅ์ด ํ์ํ์ง๋ง raw SQL์ ์ฌ์ฉํ๊ณ ์ถ์ง ์์ ๋ ORDER BY ์ ์์ sql ํ
ํ๋ฆฟ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
import { sql } from 'drizzle-orm'
import { usersTable } from 'schema'
await db.select().from(usersTable).orderBy(sql`${usersTable.id} desc nulls first`)select * from "users" order by "users"."id" desc nulls first;having๊ณผ groupBy์์ sql ์ฌ์ฉํ๊ธฐ
Drizzle์์ ์ฌ์ฉํ ์ ์๋ ํน์ ๊ธฐ๋ฅ์ด ํ์ํ์ง๋ง raw SQL์ ์ฌ์ฉํ๊ณ ์ถ์ง ์์ ๋ HAVING๊ณผ GROUP BY ์ ์์ sql ํ
ํ๋ฆฟ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
import { sql } from 'drizzle-orm'
import { usersTable } from 'schema'
await db.select({
projectId: usersTable.projectId,
count: sql<number>`count(${usersTable.id})`.mapWith(Number)
}).from(usersTable)
.groupBy(sql`${usersTable.projectId}`)
.having(sql`count(${usersTable.id}) > 300`)select "project_id", count("users"."id") from users group by "users"."project_id" having count("users"."id") > 300;