Home > Blog > tech

Drizzle ORM คืออะไร? Type-Safe SQL ที่เร็วและเบาที่สุดสำหรับ TypeScript Developer 2026

drizzle orm type safe sql guide
Drizzle ORM Type-Safe SQL Guide 2026
2026-04-11 | tech | 3400 words

ในโลกของ TypeScript และ JavaScript สมัยใหม่ การเลือก ORM ที่เหมาะสมเป็นเรื่องสำคัญมาก Drizzle ORM เป็นตัวเลือกที่กำลังได้รับความนิยมอย่างรวดเร็วในปี 2026 เพราะมันเบา เร็ว และที่สำคัญคือ Type-Safe อย่างแท้จริง ไม่ต้องมี Code Generation ที่ยุ่งยากแบบ Prisma อีกต่อไป

บทความนี้จะพาคุณเรียนรู้ Drizzle ORM ตั้งแต่แนวคิดพื้นฐานไปจนถึงการใช้งานจริงกับ Framework ยอดนิยม พร้อมเปรียบเทียบกับ ORM ตัวอื่นอย่างละเอียด เพื่อให้คุณตัดสินใจได้ว่า Drizzle เหมาะกับโปรเจกต์ของคุณหรือไม่

Drizzle ORM คืออะไร?

Drizzle ORM คือ TypeScript ORM ที่ออกแบบมาให้มีลักษณะคล้าย SQL มากที่สุด แนวคิดหลักของ Drizzle คือ ถ้าคุณรู้จัก SQL คุณก็รู้จัก Drizzle โดยไม่ต้องเรียนรู้ API ใหม่ทั้งหมดเหมือน ORM ตัวอื่น Drizzle ถูกสร้างขึ้นด้วยปรัชญาว่า ORM ไม่ควรเป็นตัวกั้นระหว่าง Developer กับ Database

จุดเด่นของ Drizzle ที่แตกต่างจาก ORM ทั่วไปคือ:

ปรัชญาของ Drizzle: If you know SQL, you know Drizzle

Drizzle ยึดหลักว่า SQL เป็นภาษาที่ทรงพลังอยู่แล้ว ไม่ควรซ่อนมันไว้หลัง Abstraction Layer ที่หนาเกินไป ORM หลายตัวพยายามสร้าง API ของตัวเองที่ไม่เหมือน SQL เลย ทำให้ Developer ต้องเรียนรู้ทั้ง SQL และ ORM API แยกกัน Drizzle แก้ปัญหานี้ด้วยการทำให้ API ของมันคล้ายกับ SQL มากที่สุด

ตัวอย่างเช่น ถ้าคุณเขียน SQL ว่า SELECT * FROM users WHERE age > 18 ORDER BY name ใน Drizzle จะเขียนเป็น db.select().from(users).where(gt(users.age, 18)).orderBy(users.name) ซึ่งอ่านแล้วเข้าใจทันทีว่ามันทำอะไร

นอกจากนี้ Drizzle ยังรองรับ Raw SQL ได้ทุกที่ผ่าน sql template literal ทำให้คุณไม่มีทางติดขัดเพราะ ORM ไม่รองรับ Query ที่ซับซ้อน สิ่งนี้เป็นข้อจำกัดที่พบบ่อยใน ORM อื่นๆ

การติดตั้ง Drizzle ORM

# ติดตั้ง Drizzle ORM core
npm install drizzle-orm

# ติดตั้ง Driver สำหรับ Database ที่ใช้
# PostgreSQL
npm install drizzle-orm postgres
npm install -D drizzle-kit

# MySQL
npm install drizzle-orm mysql2
npm install -D drizzle-kit

# SQLite
npm install drizzle-orm better-sqlite3
npm install -D drizzle-kit @types/better-sqlite3

# Turso (LibSQL)
npm install drizzle-orm @libsql/client
npm install -D drizzle-kit

# Neon Serverless
npm install drizzle-orm @neondatabase/serverless
npm install -D drizzle-kit

Schema Definition — การกำหนดโครงสร้างตาราง

Drizzle ใช้ TypeScript ในการกำหนด Schema แทนที่จะใช้ไฟล์ DSL แยกต่างหากเหมือน Prisma Schema ข้อดีคือคุณได้ Type Safety ตั้งแต่ตอน Define Schema เลย และสามารถใช้ TypeScript features ทั้งหมดได้

PostgreSQL Schema

import { pgTable, serial, text, varchar, integer,
         boolean, timestamp, pgEnum } from 'drizzle-orm/pg-core';

// กำหนด Enum
export const roleEnum = pgEnum('role', ['admin', 'user', 'moderator']);

// ตาราง Users
export const users = pgTable('users', {
  id: serial('id').primaryKey(),
  name: text('name').notNull(),
  email: varchar('email', { length: 255 }).notNull().unique(),
  role: roleEnum('role').default('user'),
  age: integer('age'),
  isActive: boolean('is_active').default(true),
  createdAt: timestamp('created_at').defaultNow(),
  updatedAt: timestamp('updated_at').defaultNow(),
});

// ตาราง Posts
export const posts = pgTable('posts', {
  id: serial('id').primaryKey(),
  title: text('title').notNull(),
  content: text('content'),
  authorId: integer('author_id').references(() => users.id),
  published: boolean('published').default(false),
  createdAt: timestamp('created_at').defaultNow(),
});

// ตาราง Comments
export const comments = pgTable('comments', {
  id: serial('id').primaryKey(),
  text: text('text').notNull(),
  postId: integer('post_id').references(() => posts.id),
  userId: integer('user_id').references(() => users.id),
  createdAt: timestamp('created_at').defaultNow(),
});

MySQL Schema

import { mysqlTable, serial, text, varchar,
         int, boolean, timestamp } from 'drizzle-orm/mysql-core';

export const users = mysqlTable('users', {
  id: serial('id').primaryKey(),
  name: text('name').notNull(),
  email: varchar('email', { length: 255 }).notNull().unique(),
  age: int('age'),
  createdAt: timestamp('created_at').defaultNow(),
});

SQLite Schema

import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';

export const users = sqliteTable('users', {
  id: integer('id').primaryKey({ autoIncrement: true }),
  name: text('name').notNull(),
  email: text('email').notNull().unique(),
  age: integer('age'),
});

Relations — การกำหนดความสัมพันธ์

Drizzle แยกการกำหนด Relations ออกจาก Schema เพื่อให้ Schema ตรงกับ Database จริงๆ ในขณะที่ Relations เป็น Application-level concept สำหรับใช้กับ Relational Query API

import { relations } from 'drizzle-orm';

export const usersRelations = relations(users, ({ many }) => ({
  posts: many(posts),
  comments: many(comments),
}));

export const postsRelations = relations(posts, ({ one, many }) => ({
  author: one(users, {
    fields: [posts.authorId],
    references: [users.id],
  }),
  comments: many(comments),
}));

export const commentsRelations = relations(comments, ({ one }) => ({
  post: one(posts, {
    fields: [comments.postId],
    references: [posts.id],
  }),
  user: one(users, {
    fields: [comments.userId],
    references: [users.id],
  }),
}));

Query Builder — การ Query ข้อมูล

การเชื่อมต่อ Database

import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import * as schema from './schema';

const client = postgres(process.env.DATABASE_URL!);
const db = drizzle(client, { schema });

SELECT — ดึงข้อมูล

// SELECT * FROM users
const allUsers = await db.select().from(users);

// SELECT ด้วย WHERE
import { eq, gt, like, and, or, ne, between, inArray } from 'drizzle-orm';

// WHERE age > 18
const adults = await db.select().from(users).where(gt(users.age, 18));

// WHERE email LIKE '%@gmail.com'
const gmailUsers = await db.select().from(users)
  .where(like(users.email, '%@gmail.com'));

// WHERE age > 18 AND isActive = true
const activeAdults = await db.select().from(users)
  .where(and(gt(users.age, 18), eq(users.isActive, true)));

// WHERE role IN ('admin', 'moderator')
const staff = await db.select().from(users)
  .where(inArray(users.role, ['admin', 'moderator']));

// SELECT เฉพาะบาง Column
const userNames = await db.select({
  id: users.id,
  name: users.name,
}).from(users);

// ORDER BY, LIMIT, OFFSET
const paged = await db.select().from(users)
  .orderBy(users.name)
  .limit(10)
  .offset(20);

INSERT — เพิ่มข้อมูล

// INSERT เดี่ยว
await db.insert(users).values({
  name: 'สมชาย',
  email: 'somchai@example.com',
  age: 25,
});

// INSERT หลายรายการ
await db.insert(users).values([
  { name: 'สมชาย', email: 'somchai@example.com', age: 25 },
  { name: 'สมหญิง', email: 'somying@example.com', age: 30 },
]);

// INSERT ... RETURNING (PostgreSQL)
const newUser = await db.insert(users).values({
  name: 'สมศรี',
  email: 'somsri@example.com',
}).returning();

// INSERT ... ON CONFLICT (Upsert)
await db.insert(users).values({
  name: 'สมชาย',
  email: 'somchai@example.com',
}).onConflictDoUpdate({
  target: users.email,
  set: { name: 'สมชาย (Updated)' },
});

UPDATE — แก้ไขข้อมูล

// UPDATE users SET name = 'ชื่อใหม่' WHERE id = 1
await db.update(users)
  .set({ name: 'ชื่อใหม่' })
  .where(eq(users.id, 1));

// UPDATE พร้อม RETURNING
const updated = await db.update(users)
  .set({ isActive: false })
  .where(lt(users.age, 18))
  .returning();

DELETE — ลบข้อมูล

// DELETE FROM users WHERE id = 1
await db.delete(users).where(eq(users.id, 1));

// DELETE พร้อม RETURNING
const deleted = await db.delete(users)
  .where(eq(users.isActive, false))
  .returning();

Joins — การ Join ตาราง

// INNER JOIN
const postsWithAuthors = await db.select({
  postTitle: posts.title,
  authorName: users.name,
}).from(posts)
  .innerJoin(users, eq(posts.authorId, users.id));

// LEFT JOIN
const usersWithPosts = await db.select({
  userName: users.name,
  postTitle: posts.title,
}).from(users)
  .leftJoin(posts, eq(users.id, posts.authorId));

// Multiple JOINs
const commentsWithDetails = await db.select({
  comment: comments.text,
  postTitle: posts.title,
  userName: users.name,
}).from(comments)
  .innerJoin(posts, eq(comments.postId, posts.id))
  .innerJoin(users, eq(comments.userId, users.id));

Aggregations และ Group By

import { count, avg, sum, max, min } from 'drizzle-orm';

// COUNT
const userCount = await db.select({
  total: count(),
}).from(users);

// GROUP BY พร้อม COUNT
const postsByAuthor = await db.select({
  authorId: posts.authorId,
  postCount: count(),
}).from(posts)
  .groupBy(posts.authorId);

// HAVING
const activeAuthors = await db.select({
  authorId: posts.authorId,
  postCount: count(),
}).from(posts)
  .groupBy(posts.authorId)
  .having(gt(count(), 5));

// AVG, SUM
const ageStats = await db.select({
  avgAge: avg(users.age),
  totalAge: sum(users.age),
  maxAge: max(users.age),
  minAge: min(users.age),
}).from(users);

Subqueries

// Subquery ใน WHERE
const subquery = db.select({ id: users.id }).from(users)
  .where(eq(users.role, 'admin'));

const adminPosts = await db.select().from(posts)
  .where(inArray(posts.authorId, subquery));

// Subquery เป็น Derived Table
const sq = db.select({
  authorId: posts.authorId,
  postCount: count().as('post_count'),
}).from(posts)
  .groupBy(posts.authorId)
  .as('post_counts');

const usersWithPostCount = await db.select({
  name: users.name,
  postCount: sq.postCount,
}).from(users)
  .leftJoin(sq, eq(users.id, sq.authorId));

Prepared Statements

Drizzle รองรับ Prepared Statements เพื่อเพิ่มประสิทธิภาพ Query ที่ถูกเรียกซ้ำบ่อยๆ และป้องกัน SQL Injection ได้อย่างสมบูรณ์

import { placeholder } from 'drizzle-orm';

// สร้าง Prepared Statement
const getUserById = db.select().from(users)
  .where(eq(users.id, placeholder('id')))
  .prepare('get_user_by_id');

// เรียกใช้ซ้ำได้หลายครั้ง
const user1 = await getUserById.execute({ id: 1 });
const user2 = await getUserById.execute({ id: 2 });

// Prepared Statement กับหลาย Parameters
const getUsersByAgeRange = db.select().from(users)
  .where(and(
    gt(users.age, placeholder('minAge')),
    lt(users.age, placeholder('maxAge'))
  ))
  .prepare('get_users_by_age_range');

const youngUsers = await getUsersByAgeRange.execute({ minAge: 18, maxAge: 25 });

Relational Queries — Query แบบ Nested

นอกจาก SQL-like Query Builder แล้ว Drizzle ยังมี Relational Query API ที่ช่วยให้ดึงข้อมูลแบบ Nested ได้ง่ายขึ้น คล้ายกับ Prisma include แต่ยังคง Type-Safe เหมือนเดิม

// ดึง Users พร้อม Posts ทั้งหมด
const usersWithPosts = await db.query.users.findMany({
  with: {
    posts: true,
  },
});

// ดึง Posts พร้อม Author และ Comments
const postsWithDetails = await db.query.posts.findMany({
  with: {
    author: true,
    comments: {
      with: {
        user: true,
      },
    },
  },
  where: eq(posts.published, true),
  orderBy: [desc(posts.createdAt)],
  limit: 10,
});

// เลือกเฉพาะบาง Column
const slimPosts = await db.query.posts.findMany({
  columns: {
    id: true,
    title: true,
  },
  with: {
    author: {
      columns: {
        name: true,
      },
    },
  },
});

// findFirst
const firstAdmin = await db.query.users.findFirst({
  where: eq(users.role, 'admin'),
});

Drizzle Kit — Migrations และ Schema Management

Drizzle Kit เป็นเครื่องมือ CLI ที่ช่วยจัดการ Database Migrations มันจะอ่าน Schema ของคุณแล้วสร้าง SQL Migration Files ให้อัตโนมัติ

Configuration

// drizzle.config.ts
import { defineConfig } from 'drizzle-kit';

export default defineConfig({
  schema: './src/db/schema.ts',
  out: './drizzle',
  dialect: 'postgresql',
  dbCredentials: {
    url: process.env.DATABASE_URL!,
  },
});

คำสั่ง Drizzle Kit

# สร้าง Migration จาก Schema ที่เปลี่ยนแปลง
npx drizzle-kit generate

# ดู SQL ที่จะถูก Run
npx drizzle-kit migrate

# Push Schema ตรงไป Database (Development)
npx drizzle-kit push

# ดึง Schema จาก Database ที่มีอยู่
npx drizzle-kit introspect

# ตรวจสอบว่า Schema ตรงกับ Database หรือไม่
npx drizzle-kit check

# เปิด Drizzle Studio
npx drizzle-kit studio
drizzle-kit push vs generate: ใช้ push สำหรับ Development ที่ต้องการเปลี่ยน Schema บ่อยๆ ใช้ generate สำหรับ Production ที่ต้องการ Migration Files เพื่อ Track Changes

Drizzle-Zod — Validation จาก Schema

Drizzle สามารถสร้าง Zod Schema จาก Database Schema ได้อัตโนมัติ ทำให้คุณไม่ต้องเขียน Validation Schema ซ้ำซ้อน เป็น Single Source of Truth จริงๆ

npm install drizzle-zod
import { createInsertSchema, createSelectSchema } from 'drizzle-zod';
import { z } from 'zod';

// สร้าง Zod Schema อัตโนมัติ
const insertUserSchema = createInsertSchema(users);
const selectUserSchema = createSelectSchema(users);

// Customize Validation
const insertUserSchemaCustom = createInsertSchema(users, {
  email: (schema) => schema.email('กรุณากรอก Email ที่ถูกต้อง'),
  name: (schema) => schema.min(2, 'ชื่อต้องมีอย่างน้อย 2 ตัวอักษร'),
  age: (schema) => schema.min(1).max(150),
});

// ใช้กับ API Route
app.post('/users', async (req, res) => {
  const result = insertUserSchemaCustom.safeParse(req.body);
  if (!result.success) {
    return res.status(400).json(result.error);
  }
  const user = await db.insert(users).values(result.data).returning();
  res.json(user);
});

Drizzle Studio

Drizzle Studio เป็น GUI สำหรับจัดการ Database ที่มาพร้อมกับ Drizzle Kit ใช้ง่าย ดูข้อมูล แก้ไขข้อมูล และ Run Query ได้ผ่าน Browser โดยไม่ต้องติดตั้งอะไรเพิ่ม

# เปิด Drizzle Studio
npx drizzle-kit studio

# จะเปิด Browser ที่ https://local.drizzle.studio

Drizzle Studio รองรับการดูโครงสร้างตาราง การ Browse ข้อมูล การแก้ไขข้อมูลแบบ Inline การ Filter และ Sort รวมถึงการ Export ข้อมูลเป็น CSV ซึ่งสะดวกมากสำหรับการ Debug และจัดการข้อมูลระหว่างการพัฒนา

Drizzle กับ Framework ยอดนิยม

Next.js

// src/db/index.ts
import { drizzle } from 'drizzle-orm/neon-http';
import { neon } from '@neondatabase/serverless';
import * as schema from './schema';

const sql = neon(process.env.DATABASE_URL!);
export const db = drizzle(sql, { schema });

// app/api/users/route.ts
import { db } from '@/db';
import { users } from '@/db/schema';

export async function GET() {
  const allUsers = await db.query.users.findMany();
  return Response.json(allUsers);
}

Hono

import { Hono } from 'hono';
import { drizzle } from 'drizzle-orm/d1';
import * as schema from './schema';

const app = new Hono<{ Bindings: { DB: D1Database } }>()

app.get('/users', async (c) => {
  const db = drizzle(c.env.DB, { schema });
  const users = await db.query.users.findMany();
  return c.json(users);
});

Nuxt

// server/utils/db.ts
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import * as schema from '../db/schema';

const client = postgres(process.env.DATABASE_URL!);
export const db = drizzle(client, { schema });

// server/api/users.get.ts
export default defineEventHandler(async () => {
  return await db.query.users.findMany();
});

SvelteKit

// src/lib/server/db.ts
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import * as schema from './schema';

const client = postgres(process.env.DATABASE_URL!);
export const db = drizzle(client, { schema });

// src/routes/users/+page.server.ts
import { db } from '$lib/server/db';
import { users } from '$lib/server/schema';

export async function load() {
  const allUsers = await db.query.users.findMany();
  return { users: allUsers };
}

Database Support — ฐานข้อมูลที่รองรับ

Drizzle รองรับฐานข้อมูลหลากหลายตัว ทั้ง Traditional Database และ Serverless Database ซึ่งเป็นจุดแข็งที่สำคัญ:

DatabaseDriverใช้กับ
PostgreSQLpostgres, node-postgres, NeonProduction ทั่วไป
MySQLmysql2, PlanetScaleProduction ทั่วไป
SQLitebetter-sqlite3, Bun SQLiteLocal Development, Embedded
Cloudflare D1D1 DriverCloudflare Workers
Turso (LibSQL)@libsql/clientEdge, Embedded Replicas
Neon@neondatabase/serverlessServerless PostgreSQL
PlanetScale@planetscale/databaseServerless MySQL
Vercel Postgres@vercel/postgresVercel Platform
SupabasepostgresSupabase Platform

Performance Benchmarks — Drizzle vs Prisma

ในการทดสอบประสิทธิภาพที่ทำในปี 2026 Drizzle แสดงให้เห็นว่ามีความเร็วที่เหนือกว่า Prisma อย่างชัดเจนในหลายด้าน โดยเฉพาะเรื่อง Cold Start และ Bundle Size ซึ่งสำคัญมากสำหรับ Serverless

MetricDrizzle ORMPrisma
Bundle Size~60 KB~2.5 MB+ (Engine)
Cold Start< 10ms~200-500ms
Simple SELECT~0.3ms~1.2ms
JOIN Query~0.8ms~3.5ms
Code Generationไม่ต้องต้อง run generate
Memory Usageต่ำมากสูง (Rust Engine)
สาเหตุที่ Drizzle เร็วกว่า: Drizzle ทำงานเป็น Pure TypeScript โดยตรง ไม่มี Binary Engine เหมือน Prisma ที่ต้อง Load Rust Query Engine ทำให้ Cold Start เร็วกว่ามากใน Serverless

Drizzle vs Prisma vs TypeORM — เปรียบเทียบรอบด้าน

FeatureDrizzlePrismaTypeORM
Type Safety100% (Compile-time)ดี (Generated Types)ปานกลาง
Learning Curveต่ำ (ถ้ารู้ SQL)ปานกลางสูง
SQL-like APIมากน้อย (Custom API)ปานกลาง
Code Generationไม่ต้องต้องไม่ต้อง
Bundle Sizeเล็กมากใหญ่ปานกลาง
Serverlessดีเยี่ยมปานกลางไม่ค่อยเหมาะ
Raw SQLดีเยี่ยมจำกัดดี
MigrationDrizzle KitPrisma MigrateBuilt-in
GUI ToolDrizzle StudioPrisma Studioไม่มี
Communityกำลังโตใหญ่ใหญ่
Edge Runtimeรองรับจำกัดไม่รองรับ

Batch Operations

Drizzle รองรับการทำ Batch Operations เพื่อส่งหลาย Query ไปยัง Database ในรอบเดียว ลด Round-trip และเพิ่มประสิทธิภาพ

// Batch Insert
await db.insert(users).values([
  { name: 'User 1', email: 'user1@example.com' },
  { name: 'User 2', email: 'user2@example.com' },
  { name: 'User 3', email: 'user3@example.com' },
  // ... สามารถใส่ได้หลายพันรายการ
]);

// Transaction
await db.transaction(async (tx) => {
  const newUser = await tx.insert(users).values({
    name: 'สมชาย',
    email: 'somchai@example.com',
  }).returning();

  await tx.insert(posts).values({
    title: 'บทความแรก',
    authorId: newUser[0].id,
  });
});

// Batch Queries (ส่งหลาย Query พร้อมกัน)
const [allUsers, allPosts, userCount] = await db.batch([
  db.select().from(users),
  db.select().from(posts),
  db.select({ count: count() }).from(users),
]);

Custom Types

Drizzle ให้คุณสร้าง Custom Column Types ได้ เพื่อจัดการกับ Data Types ที่ไม่ได้มีอยู่ใน Built-in Types เช่น JSON, Array หรือ Custom Formats

import { customType } from 'drizzle-orm/pg-core';

// Custom JSON Type ที่ Type-Safe
const jsonb = () => customType<{ data: T; driverData: string }>({
  dataType() {
    return 'jsonb';
  },
  toDriver(value: T): string {
    return JSON.stringify(value);
  },
  fromDriver(value: string): T {
    return JSON.parse(value) as T;
  },
});

// ใช้งาน
interface UserPreferences {
  theme: 'light' | 'dark';
  language: string;
  notifications: boolean;
}

export const userSettings = pgTable('user_settings', {
  id: serial('id').primaryKey(),
  userId: integer('user_id').references(() => users.id),
  preferences: jsonb()('preferences').notNull(),
});

เมื่อไหร่ควรเลือก Drizzle เมื่อไหร่ควรเลือก Prisma?

เลือก Drizzle เมื่อ:

เลือก Prisma เมื่อ:

Best Practices สำหรับ Drizzle ORM

import { index, uniqueIndex } from 'drizzle-orm/pg-core';

export const users = pgTable('users', {
  id: serial('id').primaryKey(),
  email: varchar('email', { length: 255 }).notNull(),
  name: text('name'),
  createdAt: timestamp('created_at').defaultNow(),
}, (table) => ({
  emailIdx: uniqueIndex('email_idx').on(table.email),
  nameIdx: index('name_idx').on(table.name),
}));

สรุป

Drizzle ORM เป็นทางเลือกที่ยอดเยี่ยมสำหรับ TypeScript Developer ที่ต้องการ ORM ที่เบา เร็ว Type-Safe และไม่ซ่อน SQL ไว้หลัง Abstraction ที่ซับซ้อน ด้วยปรัชญา If you know SQL you know Drizzle ทำให้การเรียนรู้เป็นเรื่องง่ายสำหรับ Developer ที่มีพื้นฐาน SQL อยู่แล้ว

ในปี 2026 Drizzle กำลังเติบโตอย่างรวดเร็วและกลายเป็นตัวเลือกอันดับต้นๆ สำหรับ Serverless และ Edge Computing ถ้าคุณกำลังเริ่มโปรเจกต์ใหม่ด้วย TypeScript ลอง Drizzle ดูสักครั้ง คุณอาจไม่อยากกลับไปใช้ ORM ตัวอื่นอีกเลย เพราะมันทำให้การทำงานกับ Database เป็นเรื่องสนุกและปลอดภัยไปพร้อมกัน


Back to Blog | iCafe Forex | SiamLanCard | Siam2R