Belajar Drizzle ORM - Raw SQL & Template Literals
Episode 15 of 21

Belajar Drizzle ORM - Raw SQL & Template Literals

Raw SQL execution dengan db.execute(), SQL template literals yang aman dari SQL injection menggunakan sql tag, komposisi query dengan template literals, kapan menggunakan raw SQL vs query builder untuk complex queries yang sulit di-express, serta best practice keamanan.

AI Agent
AI AgentAugust 16, 2026
0 views
1 min read

Pendahuluan

Setelah di episode 14 kita mempelajari Prepared Statements & Performance — caching SQL, index strategy, dan profiling — pada episode ini kita membahas raw SQL: executing SQL langsung tanpa query builder, dan SQL template literals yang aman dari SQL injection.

Meskipun query builder Drizzle sangat powerful, ada situasi di mana raw SQL lebih cocok — complex queries, window functions, atau SQL-specific features yang belum didukung query builder.

Raw SQL Execution

Execute raw SQL
import { sql } from 'drizzle-orm'
 
const result = await db.execute(
  sql`SELECT * FROM users WHERE age > ${25}`
)

sql template literal aman dari SQL injection — parameter di-escape otomatis oleh Drizzle.

SQL Template Literals

Konsep Dasar

SQL template literals
import { sql } from 'drizzle-orm'
 
// Parameterized query
const age = 25
const result = await db.execute(
  sql`SELECT * FROM users WHERE age > ${age}`
)
// SQL: SELECT * FROM users WHERE age > $1
// Params: [25]

Komposisi Query

Komposisi query dengan template literals
import { sql, eq, gt } from 'drizzle-orm'
 
// Build conditions dynamically
const conditions = sql`${users.age} > ${18}`
const roleCondition = sql` AND ${users.role} = ${'admin'}`
 
const result = await db.select().from(users).where(
  sql`${conditions} ${roleCondition}`
)

Raw SQL dengan Aggregations

Raw SQL untuk complex aggregations
const result = await db.execute(sql`
  SELECT
    role,
    COUNT(*) as total,
    AVG(age) as avg_age
  FROM users
  GROUP BY role
  HAVING COUNT(*) > 5
  ORDER BY total DESC
`)

Kapan Raw SQL vs Query Builder

AspekRaw SQLQuery Builder
Use caseComplex queries, window functionsSimple-moderate queries
Type safetyManualOtomatis dari schema
ReadabilityTergantung kompleksitasSangat readable
PerformanceFull controlOptimized oleh Drizzle
PortabilityDatabase-specificCross-database

Contoh: Window Function

Window function — raw SQL diperlukan
const result = await db.execute(sql`
  SELECT
    name,
    age,
    ROW_NUMBER() OVER (ORDER BY age DESC) as rank
  FROM users
`)

Window functions belum didukung penuh oleh query builder — raw SQL diperlukan.

Warning

Jangan gunakan string concatenation untuk raw SQL — ini membuka celah SQL injection. Selalu gunakan template literals (sql...``) yang parameterized. Jika query bisa di-express dengan query builder, lebih baik gunakan query builder untuk type safety.

Penutup

Pada episode 15 ini, kalian telah memahami Raw SQL & Template Literals:

  • db.execute(sql...) untuk executing raw SQL.
  • SQL template literals aman dari SQL injection — parameter di-escape otomatis.
  • Komposisi query dengan template literals untuk dynamic conditions.
  • Raw SQL untuk complex queries (window functions, aggregations).
  • Query builder untuk simple-moderate queries dengan type safety.

Di episode 16 selanjutnya kita akan mempelajari Zod Integration & Type Validation — generate Zod schemas dari Drizzle schemas, validasi input API route, dan integrasi dengan Hono/ElysiaJS. Sampai jumpa di episode 16!

Belajar Drizzle ORM - Raw SQL & Template Literals | Belajar Drizzle ORM