You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SvelteKit/Prisma中URL去撇号后的数据库查询问题

解决方案:解决URL参数与数据库名称匹配的字符问题

核心问题

你当前的方案通过将带撇号的名称转成短横线形式的URL(如User's Spellbook→users-spellbook),但反向转换后丢失了撇号,导致无法匹配数据库中的原名称。contains未生效大概率是因为MySQL默认区分大小写,且转换后的字符串与原名称差异(缺失撇号)导致匹配失败。

推荐以下两种可靠方案:


方案1:使用Spellbook的ID作为URL参数(最简洁可靠)

直接用数据库中Spellbook的唯一ID代替名称作为URL参数,彻底规避字符编码问题:

  1. 修改路由路径为 /spellbooks/[spellbookId]
  2. 更新+page.server.ts代码:
import { prisma } from '$lib/server/prisma';
import type { RequestHandler } from '@sveltejs/kit';

export const GET: RequestHandler = async ({ params }) => {
    const spellbookId = parseInt(params.spellbookId);
    if (isNaN(spellbookId)) {
        return new Response(JSON.stringify({ message: '无效的咒语本ID' }), { status: 400 });
    }

    const spellbook = await prisma.spellbook.findUnique({
        where: { id: spellbookId },
        include: {
            spells: {
                include: {
                    classes: true,
                    components: true,
                    description_list: true
                }
            }
        }
    });

    if (!spellbook) {
        return new Response(JSON.stringify({ message: '未找到对应咒语本' }), { status: 404 });
    }

    return new Response(JSON.stringify(spellbook), { status: 200 });
};

方案2:新增Slug字段专门用于URL(保留名称语义)

在数据库中存储一个专门用于URL的标准化slug字段,创建咒语本时生成对应的slug,查询时直接匹配:

  1. 更新schema.prisma的Spellbook模型,新增slug字段:
model Spellbook {
  id                    Int      @id @default(autoincrement())
  user_id               String
  spellbook_name        String   @unique
  slug                  String   @unique // 新增:用于URL的标准化名称
  character_name        String
  spellbook_description String?  @db.VarChar(1000)
  class                 Class
  image_url             String
  created_at            DateTime @default(now())
  updated_at            DateTime @updatedAt
  auth_user             AuthUser @relation(fields: [user_id], references: [id])
  spells                Spell[]  @relation("SpellToSpellbook")

  @@index([user_id])
  @@map("spellbook")
}

执行prisma migrate dev更新数据库结构。

  1. 编写slug生成函数,在创建咒语本时生成对应的slug:
function generateSlug(name: string): string {
  return name
    .toLowerCase()
    .replace(/['’]/g, '') // 移除撇号
    .replace(/\s+/g, '-') // 空格替换为短横线
    .replace(/[^a-z0-9-]/g, ''); // 移除其他特殊字符
}

// 创建咒语本时调用
await prisma.spellbook.create({
  data: {
    spellbook_name: "User's Spellbook",
    slug: generateSlug("User's Spellbook"), // 生成users-spellbook
    user_id: "xxx",
    character_name: "xxx",
    class: "Wizard",
    image_url: "xxx"
  }
});
  1. 修改+page.server.ts直接匹配slug:
import { prisma } from '$lib/server/prisma';
import type { RequestHandler } from '@sveltejs/kit';

export const GET: RequestHandler = async ({ params }) => {
    const slug = params.spellbookName;
    const spellbook = await prisma.spellbook.findFirst({
        where: { slug },
        include: {
            spells: {
                include: {
                    classes: true,
                    components: true,
                    description_list: true
                }
            }
        }
    });

    if (!spellbook) {
        return new Response(JSON.stringify({ message: '未找到对应咒语本' }), { status: 404 });
    }

    return new Response(JSON.stringify(spellbook), { status: 200 });
};

临时应急方案(不推荐)

如果暂时无法修改数据库,可尝试不区分大小写的模糊匹配,但存在重名匹配错误的风险:

const spellbookName = params.spellbookName?.replace(/-/g, ' ');
const spellbook = await prisma.spellbook.findFirst({
    where: {
        spellbook_name: {
            contains: spellbookName,
            mode: 'insensitive' // 忽略大小写
        }
    },
    include: {
        spells: {
            include: {
                classes: true,
                components: true,
                description_list: true
            }
        }
    }
});

内容的提问来源于stack exchange,提问作者ezzy-dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 03:17:06