跳转至内容
There is a version suitable for your browser's language settings. Would you like to go to the english language of the site?
主页文档

用法

H1

Drizzle 使用了与原生 SQL 非常接近的语法。本章节将详细介绍 Drizzle 的一些常见用法,以便于没有 SQL 基础的读者快速入门,并同时阐述 Drizzle 与 Milkio 的最佳结合方式。

BREAD 操作

BREAD 操作指南覆盖了表的基本操作:添加、检索、更新、删除。

添加

向表中添加新数据。

import { useDrizzle } from "/src/uses/drizzle";
import { userTable } from "/src/databases/user-table.ts";
const drizzle = await useDrizzle();
await drizzle.insert(userTable).values({ name: 'Amber', email: 'amber@example.com', gender: 'female' });

修改

根据条件修改数据。

import { useDrizzle } from "/src/uses/drizzle";
import { userTable } from "/src/databases/user-table.ts";
const drizzle = await useDrizzle();
await drizzle.update(userTable).set({ name: 'Kirsi' }).where(eq(userTable.name, 'Amber'));

删除

根据条件删除数据。

import { useDrizzle } from "/src/uses/drizzle";
import { userTable } from "/src/databases/user-table.ts";
const drizzle = await useDrizzle();
await drizzle.delete(userTable).where(eq(userTable.name, 'Kirsi'));

获取一列

获取满足条件的第一条数据。

import { useDrizzle } from "/src/uses/drizzle";
import { userTable } from "/src/databases/user-table.ts";
const drizzle = await useDrizzle();
const result = await drizzle.query.table.findFirst({
where: (table, query) => query.eq(table.name, 'Reynard'),
});

获取所有列并排序

获取所有数据并按 created_at 排序。

import { useDrizzle } from "/src/uses/drizzle";
import { userTable } from "/src/databases/user-table.ts";
const drizzle = await useDrizzle();
const result = await drizzle.query.table.findMany({
orderBy: userTable.created_at,
});

分页获取

分页获取数据以减少服务器压力。

import { useDrizzle } from "/src/uses/drizzle";
import { userTable } from "/src/databases/user-table.ts";
const drizzle = await useDrizzle();
const args = { page: 1, pageSize: 10 };
const result = await db.query.userTable.findMany({
orderBy: userTable.created_at,
offset: (Number(args.page) - 1) * Number(args.pageSize),
limit: Number(args.pageSize),
});
console.log(result);

关联关系

数据库表之间通常存在关联关系,例如用户与用户信息、文章与评论、用户与组织等。

一对一

用户信息表通过 userId 与用户表关联。

/src/databases/user-table.ts
export const userTable = mysqlTable(
"user", // 表名
{
id: bigint("id", { mode: "bigint" }).autoincrement().primaryKey(),
name: varchar("name", { length: 255 }).notNull(),
},
t => ({})
);
export const userRelations = relations(userTable, ({ one, many }) => ({
userInfo: one(userInfoTable),
}));

一对多

文章表与评论表通过 articleId 关联,一篇文章可以有多条评论。

/src/databases/article-table.ts
export const articleTable = mysqlTable(
"article", // 表名
{
id: bigint("id", { mode: "bigint" }).autoincrement().primaryKey(),
title: varchar("title", { length: 255 }).notNull(),
content: text("content").notNull(),
},
t => ({})
);
export const articleRelations = relations(articleTable, ({ one, many }) => ({
comment: many(commentTable),
}));

多对多

用户和组织表通过中间表 userToOrg 关联。

/src/databases/user-to-org-table.ts
export const userToOrgTable = mysqlTable(
"userToOrg", // 表名
{
userId: bigint("userId", { mode: "bigint" }).notNull(),
orgId: bigint("orgId", { mode: "bigint" }).notNull(),
},
t => ({})
);
export const userToOrgRelations = relations(userToOrgTable, ({ one, many }) => ({
user: one(userTable),
org: one(orgTable),
}));

关系查询

在 Drizzle 中,使用 with 参数来查询关联数据。

import { useDrizzle } from "/src/uses/drizzle";
import { articleTable } from "/src/databases/article-table.ts";
const drizzle = await useDrizzle();
const result = await drizzle.query.articleTable.findMany({
where: (table, query) => query.eq(table.title, "Hello World"),
with: {
comment: true,
}
});

类型安全

Milkio 依据 TypeScript 类型来限制 API 参数,利用表的类型直接定义 API 参数,确保参数类型与数据库结构一致。

/src/apps/user/add.ts
import { defineApi } from "milkio";
import { DBInsert } from "milkio-drizzle";
import { userTable } from "../generated/database-schema";
export const api = defineApi({
meta: {},
async action(
params: {
user: DBInsert<typeof userTable>;
},
context
) {
const drizzle = await useDrizzle();
await drizzle.insert(userTable).values(params.user);
},
});

类型标签

通过 $type 属性,可以在表中添加类型标签和更严格的类型约束。

export const userTable = mysqlTable(
"user",
{
id: int("id", { unsigned: true }).autoincrement().primaryKey(),
name: varchar("name", { length: 32 }).$type<string & typia.tags.MaxLength<32>>(),
avatar: varchar("avatar", { length: 255 }).$type<string & typia.tags.Format<"url">>(),
email: varchar("email", { length: 320 }).unique().$type<string & typia.tags.Format<"email">>(),
gender: varchar("gender", { length: 320 }).unique().$type<"male" | "female" | "other">(),
createdAt: datetime("createdAt").notNull().default(sql`CURRENT_TIMESTAMP`),
updatedAt: datetime("updatedAt").notNull().default(sql`CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`),
},
(t) => ({})
);

JSON 类型

MySQL 和 PostgreSQL 支持 JSON 类型,这允许存储灵活的数据结构。用户表可以这样定义:

/src/databases/user-table.ts
export const userTable = mysqlTable(
"user",
{
id: int("id", { unsigned: true }).autoincrement().primaryKey(),
// 如果使用 PostgreSQL,推荐使用 `jsonb`
data: json("data").$type<{ name: string, email: string, gender: 'male' | 'female' | 'other' }>().notNull(),
createdAt: datetime("createdAt").notNull().default(sql`CURRENT_TIMESTAMP`),
updatedAt: datetime("updatedAt").notNull().default(sql`CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`),
},
(t) => ({})
);

下一步?

Drizzle 还有很多好用的地方,阅读 Drizzle 的文档来深入了解吧!