数据操作

我将通过一个笔记 Demo 来说明如何在 NuxtBase 中使用 Supabase 数据库进行 CRUD 操作。这是 NuxtBase 内置的一个示例项目,你可以在「控制台」中找到。

笔记示例

你可在你的项目中隐藏或者移除对应的数据表和组件,以满足你的项目需求。

创建数据表

1. 基础建表语句

首先,我们需要创建一个基础的数据表结构:

create table public.nuxtbase_demo_notes (
    id bigint generated always as identity,
    content text not null,
    created_at timestamp with time zone not null default timezone ('utc'::text, now()),
    user_id uuid not null,
    updated_at timestamp with time zone not null default timezone ('utc'::text, now()),
    constraint nuxtbase_demo_notes_pkey primary key (id)
) tablespace pg_default;

2. 启用行级安全(RLS)

为了确保数据安全,我们需要启用行级安全策略:

-- 启用行级安全策略
alter table public.nuxtbase_demo_notes enable row level security;

-- 创建行级安全策略
create policy "Users can only access their own notes" on public.nuxtbase_demo_notes
  for all using (auth.uid() = user_id);

这个策略确保用户只能访问自己的笔记数据。

3. 创建自动更新时间的触发器

为了自动更新记录的修改时间,我们创建一个触发器:

-- 创建更新 updated_at 的触发器函数
create or replace function update_updated_at_column()
returns trigger as $$
begin
    new.updated_at = now();
    return new;
end;
$$ language plpgsql;

-- 创建触发器
create trigger update_nuxtbase_demo_notes_updated_at
    before update on nuxtbase_demo_notes
    for each row
    execute function update_updated_at_column();

CRUD 操作示例

下面通过一个笔记管理的前端组件来展示如何使用 Supabase SDK 进行 CRUD 操作。

1. 查询数据 (Read)

// 获取笔记列表
const fetchNotes = async () => {
  try {
    const { data, error } = await supabase
      .from("nuxtbase_demo_notes")
      .select("*")
      .order("created_at", { ascending: false });

    if (error) throw error;
    notes.value = data || [];
  } catch (error: any) {
    toast({
      title: "错误",
      description: error.message,
      variant: "destructive",
    });
  }
};

2. 创建数据 (Create)

const { error } = await supabase.from("nuxtbase_demo_notes").insert({
  content: noteContent.value,
});

3. 更新数据 (Update)

const { error } = await supabase
  .from("nuxtbase_demo_notes")
  .update({
    content: noteContent.value,
  })
  .eq("id", editingNoteId.value)
  .eq("user_id", user.value?.id);

4. 删除数据 (Delete)

const { error } = await supabase
  .from("nuxtbase_demo_notes")
  .delete()
  .eq("id", id);

完整示例

完整示例请参考@modules/saas/dashboard/components/DashboardNoteDemo.vue组件

进阶用法

对于更多高级用法,如:

  • 复杂查询
  • 实时订阅
  • 关联查询
  • 事务处理
  • 存储过程
  • 数据库函数

请参考 Supabase 官方文档

最佳实践

  1. 始终使用 RLS 策略保护数据安全
  2. 合理使用索引提升查询性能
  3. 使用触发器自动维护时间戳
  4. 在前端做好错误处理
  5. 使用类型定义确保类型安全
  6. 合理设计表结构和关联关系

提示: Supabase Dashboard 提供了便捷的在线 SQL 编辑器,可以方便地执行 SQL 语句和管理数据库。