NestJS中解构JSON请求并分表存储数据的技术求助
解决NestJS中JSON数据分表存储的Service层实现问题
1. 先定义请求DTO(数据传输对象)
通过DTO规范请求数据结构,确保能正确解构输入:
// src/profile/dto/nutrient-item.dto.ts export class NutrientItemDto { nutrient_id: number; quantity: number; unit: string; } // src/profile/dto/group.dto.ts export class GroupDto { group_id: number; nutrients: NutrientItemDto[]; } // src/profile/dto/create-profile.dto.ts export class CreateProfileDto { title: string; groups: GroupDto[]; }
2. Service层核心实现
假设使用TypeORM操作数据库,以下是包含事务处理的Service层关键代码,保证数据一致性:
// src/profile/profile.service.ts import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { Profile } from './entities/profile.entity'; import { Nutrient } from './entities/nutrient.entity'; import { CreateProfileDto } from './dto/create-profile.dto'; @Injectable() export class ProfileService { constructor( @InjectRepository(Profile) private profileRepository: Repository<Profile>, @InjectRepository(Nutrient) private nutrientRepository: Repository<Nutrient>, ) {} async create(createProfileDto: CreateProfileDto) { // 开启事务 const queryRunner = this.profileRepository.manager.connection.createQueryRunner(); await queryRunner.connect(); await queryRunner.startTransaction(); try { // 1. 创建Profile记录,自动生成id和时间戳 const profile = this.profileRepository.create({ title: createProfileDto.title, // 若Profile实体未配置自动生成时间戳,手动添加:createdAt: new Date() }); const savedProfile = await queryRunner.manager.save(profile); const profileId = savedProfile.id; // 2. 组装所有待插入的Nutrient数据 const nutrientRecords: Partial<Nutrient>[] = []; createProfileDto.groups.forEach(group => { group.nutrients.forEach(nutrient => { nutrientRecords.push({ profileId, groupId: group.group_id, nutrientId: nutrient.nutrient_id, quantity: nutrient.quantity, unit: nutrient.unit, }); }); }); // 3. 批量插入Nutrient记录 await queryRunner.manager.save(Nutrient, nutrientRecords); // 提交事务 await queryRunner.commitTransaction(); return { profile: savedProfile, nutrientsCount: nutrientRecords.length }; } catch (error) { // 回滚事务 await queryRunner.rollbackTransaction(); throw error; } finally { // 释放连接 await queryRunner.release(); } } }
3. 补充说明
- 实体结构要求:确保
Profile实体包含id、title、createdAt字段;Nutrient实体包含profileId、groupId、nutrientId、quantity、unit字段。 - 事务作用:避免出现Profile插入成功但Nutrients插入失败的情况,保证两张表的数据一致性。
- 批量插入优势:相比逐条插入,批量操作能显著提升数据库处理效率,适合这类多关联数据的场景。
内容的提问来源于stack exchange,提问作者user3408779
相关产品推荐
相关产品推荐

