如何减少Prisma关联查询中select/include语法的冗余代码行数
Prisma 嵌套查询冗余问题解决方案
你的数据库表结构设计符合关系型数据库的常规规范,无需重构,可通过以下两种低成本方案解决查询代码冗余问题:
方案1:提取可复用的Select配置片段
Prisma的查询参数本质是普通JavaScript对象,你可以将高频使用的选择配置抽离为独立常量,按需组合复用:
// 可统一放在单独的配置文件中,比如 /constants/prismaSelect.js // 天赋项选择配置 const wellTalentSelect = { wellTalent: { select: { contents: true } } } const interestTalentSelect = { interestTalent: { select: { contents: true } } } // 头像选择配置 const profileImageSelect = { profileImage: { select: { src: true } } } // 组合出个人资料完整选择配置 const profileSelect = { select: { id: true, department: true, introduce: true, ...wellTalentSelect, ...interestTalentSelect, ...profileImageSelect } } // 组合出带个人资料的用户选择配置 const userWithProfileSelect = { select: { id: true, nickname: true, email: true, profile: profileSelect } }
业务代码中直接复用配置即可,无需重复写嵌套结构:
const prisma = new PrismaClient(); const { userWithProfileSelect } = require('./constants/prismaSelect') const findByIdWithProfile = async (id) => { try { return await prisma.user.findUnique({ where: { id }, // 直接引入复用配置 ...userWithProfileSelect }); } catch (err) { console.error(err); } };
如果其他查询场景需要用到部分选择配置,直接引用对应片段组合即可,维护时只需修改一处配置全量生效。
方案2:封装DAO数据访问层
将所有数据库查询逻辑统一收敛到DAO层封装,业务代码不直接编写Prisma查询,只调用DAO层提供的方法:
// /dao/user.dao.js 统一存放用户相关的数据库查询 const prisma = new PrismaClient(); exports.findUserByIdWithProfile = async (id) => { try { return await prisma.user.findUnique({ where: { id }, select: { id: true, nickname: true, email: true, profile: { select: { id: true, department: true, introduce: true, wellTalent: { select: { contents: true } }, interestTalent: { select: { contents: true } }, profileImage: { select: { src: true } }, }, }, }, }); } catch (err) { console.error(err); throw err; } }
业务代码直接调用即可:
const { findUserByIdWithProfile } = require('./dao/user.dao') // 业务中需要查询时直接调用 const userInfo = await findUserByIdWithProfile(10)
后续版本升级优化建议
如果后续将Prisma升级到4.16及以上版本,还可以通过两个特性进一步简化代码:
omit属性:直接指定需要排除的字段(比如排除password字段),不用逐个声明要返回的字段- Client Extensions:给Prisma模型扩展自定义方法,直接通过
prisma.user.findByIdWithProfile(id)调用自定义查询
内容的提问来源于stack exchange,提问作者Jo In Hyeok
相关产品推荐
相关产品推荐

