我如何在 spring 引导中复制与您的家属的记录
How i can duplicate a record with your dependents in spring boot
在我的用例中,我需要创建一个端点,通过将数据从当前记录复制到创建新主键的新记录来复制记录及其相关项。
当前回复: 原始记录
[
{
"id": 1,
"name": "Grandparent One",
"parents": [
{
"id": 1,
"name": "Parent One",
"children": [
{
"id": 1,
"name": "Child One"
},
{
"id": 2,
"name": "Child Two"
}
]
}
]
}
]
预期响应: 原始记录和重复记录
[
{
"id": 1,
"name": "Grandparent One",
"parents": [
{
"id": 1,
"name": "Parent One",
"children": [
{
"id": 1,
"name": "Child One"
},
{
"id": 2,
"name": "Child Two"
}
]
}
]
},
{
"id": 2,
"name": "Grandparent One Copy",
"parents": [
{
"id": 2,
"name": "Parent One",
"children": [
{
"id": 3,
"name": "Child One"
},
{
"id": 4,
"name": "Child Two"
}
]
}
]
}
]
任何人都可以提示我如何在 GrandparentController
中实现此端点吗?
@PostMapping("{id}/duplicate")
public ResponseEntity<Grandparent> duplicate(@NonNull @PathVariable long id) {
//How to implement this endpoint?
return null;
}
我的类:
型号
祖父母
package com.example.demo.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "grandparents")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Grandparent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
Parent
package com.example.demo.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "parents")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "grandparent_id", nullable = false
, foreignKey = @ForeignKey(name = "fk_parents_grandparent1"))
private Grandparent grandparent;
private String name;
}
Children
package com.example.demo.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "children")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Children {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id", nullable = false
, foreignKey = @ForeignKey(name = "fk_children_parent1"))
private Parent parent;
private String name;
}
DTO
祖父母Post
package com.example.demo.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class GrandparentPost {
private String name;
}
ParentPost
package com.example.demo.dto;
import com.example.demo.model.Grandparent;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ParentPost {
private Grandparent grandparent;
private String name;
}
ChildrenPost
package com.example.demo.dto;
import com.example.demo.model.Parent;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ChildrenPost {
private Parent parent;
private String name;
}
祖父母回应
package com.example.demo.dto;
import com.example.demo.model.Grandparent;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
public class GrandparentResponseDto {
private Long id;
private String name;
private List<ParentResponseDto> parents;
public GrandparentResponseDto(Grandparent grandparent) {
this.id = grandparent.getId();
this.name = grandparent.getName();
}
}
Parent响应
package com.example.demo.dto;
import com.example.demo.model.Parent;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
public class ParentResponseDto {
private Long id;
private String name;
private List<ChildrenResponseDto> children;
public ParentResponseDto(Parent parent) {
this.id = parent.getId();
this.name = parent.getName();
}
}
Children响应
package com.example.demo.dto;
import com.example.demo.model.Children;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class ChildrenResponseDto {
private Long id;
private String name;
public ChildrenResponseDto(Children children) {
this.id = children.getId();
this.name = children.getName();
}
}
MAPPERS
GrandparentMapper
package com.example.demo.mapper;
import com.example.demo.dto.GrandparentPost;
import com.example.demo.model.Grandparent;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper(componentModel = "spring")
public abstract class GrandparentMapper {
public static final GrandparentMapper INSTANCE = Mappers.getMapper(GrandparentMapper.class);
public abstract Grandparent toGrandparent(GrandparentPost grandparentPost);
}
ParentMapper
package com.example.demo.mapper;
import com.example.demo.dto.ParentPost;
import com.example.demo.model.Parent;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper(componentModel = "spring")
public abstract class ParentMapper {
public static final ParentMapper INSTANCE = Mappers.getMapper(ParentMapper.class);
public abstract Parent toParent(ParentPost parentPost);
}
ChildrenMapper
package com.example.demo.mapper;
import com.example.demo.dto.ChildrenPost;
import com.example.demo.model.Children;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper(componentModel = "spring")
public abstract class ChildrenMapper {
public static final ChildrenMapper INSTANCE = Mappers.getMapper(ChildrenMapper.class);
public abstract Children toChildren(ChildrenPost childrenPost);
}
存储库
祖父母代表
package com.example.demo.repository;
import com.example.demo.model.Grandparent;
import org.springframework.data.jpa.repository.JpaRepository;
public interface GrandparentRep extends JpaRepository<Grandparent, Long> {
}
Parent代表
package com.example.demo.repository;
import com.example.demo.model.Parent;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface ParentRep extends JpaRepository<Parent, Long> {
List<Parent> findByGrandparent_Id(long grandparent);
}
Children代表
package com.example.demo.repository;
import com.example.demo.model.Children;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface ChildrenRep extends JpaRepository<Children, Long> {
List<Children> findByParent_Id(long parent);
}
服务
祖父母服务
package com.example.demo.service;
import com.example.demo.dto.GrandparentPost;
import com.example.demo.mapper.GrandparentMapper;
import com.example.demo.model.Grandparent;
import com.example.demo.repository.GrandparentRep;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class GrandparentService {
private final GrandparentRep grandparentRep;
public List<Grandparent> findAll() {
return grandparentRep.findAll();
}
public Optional<Grandparent> findById(long id) {
return grandparentRep.findById(id);
}
@Transactional
public Grandparent save(GrandparentPost grandparentPost) {
return grandparentRep.save(GrandparentMapper.INSTANCE.toGrandparent(grandparentPost));
}
}
Parent服务
package com.example.demo.service;
import com.example.demo.dto.ParentPost;
import com.example.demo.mapper.ParentMapper;
import com.example.demo.model.Parent;
import com.example.demo.repository.ParentRep;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@RequiredArgsConstructor
public class ParentService {
private final ParentRep parentRep;
public List<Parent> findBy(long grandparent) {
return parentRep.findByGrandparent_Id(grandparent);
}
@Transactional
public Parent save(ParentPost parentPost) {
return parentRep.save(ParentMapper.INSTANCE.toParent(parentPost));
}
}
Children服务
package com.example.demo.service;
import com.example.demo.dto.ChildrenPost;
import com.example.demo.mapper.ChildrenMapper;
import com.example.demo.model.Children;
import com.example.demo.model.Parent;
import com.example.demo.repository.ChildrenRep;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@RequiredArgsConstructor
public class ChildrenService {
private final ChildrenRep childrenRep;
public List<Children> findBy(long parent) {
return childrenRep.findByParent_Id(parent);
}
@Transactional
public Children save(ChildrenPost childrenPost) {
return childrenRep.save(ChildrenMapper.INSTANCE.toChildren(childrenPost));
}
}
控制器
祖父母控制器
package com.example.demo.controller;
import com.example.demo.dto.ChildrenResponseDto;
import com.example.demo.dto.GrandparentPost;
import com.example.demo.dto.GrandparentResponseDto;
import com.example.demo.dto.ParentResponseDto;
import com.example.demo.model.Grandparent;
import com.example.demo.service.ChildrenService;
import com.example.demo.service.GrandparentService;
import com.example.demo.service.ParentService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@RestController
@RequestMapping("api/v1/grandparents")
@RequiredArgsConstructor
public class GrandparentController {
private final GrandparentService grandparentService;
private final ParentService parentService;
private final ChildrenService childrenService;
@GetMapping
public ResponseEntity<List<Grandparent>> findAll() {
return ResponseEntity.ok(grandparentService.findAll());
}
@GetMapping("/{id}")
public ResponseEntity<Optional<Grandparent>> findById(@NonNull @PathVariable long id) {
return ResponseEntity.ok(grandparentService.findById(id));
}
@GetMapping("/{id}/stats")
public ResponseEntity<List<GrandparentResponseDto>> findByStats (@NonNull @PathVariable long id) {
var grandparentStatsDto = grandparentService.findById(id)
.stream()
.map(GrandparentResponseDto::new)
.collect(Collectors.toList());
//List parents
grandparentStatsDto.forEach(grandparentStatsList -> {
List<ParentResponseDto> parentResponseDto = parentService
.findBy(grandparentStatsList.getId())
.stream().map(ParentResponseDto::new)
.collect(Collectors.toList());
//List children
parentResponseDto.forEach(parentStatsList -> {
List<ChildrenResponseDto> childrenResponseDto = childrenService
.findBy(parentStatsList.getId())
.stream().map(ChildrenResponseDto::new)
.collect(Collectors.toList());
parentStatsList.setChildren(childrenResponseDto);
});
grandparentStatsList.setParents(parentResponseDto);
});
return ResponseEntity.ok(grandparentStatsDto);
}
@PostMapping
public ResponseEntity<Grandparent> save(@NonNull @Valid @RequestBody GrandparentPost grandparentPost) {
return new ResponseEntity<>(grandparentService.save(grandparentPost), HttpStatus.CREATED);
}
@PostMapping("{id}/duplicate")
public ResponseEntity<Grandparent> duplicate(@NonNull @PathVariable long id) {
//How to implement this endpoint?
return null;
}
}
Parent控制器
package com.example.demo.controller;
import com.example.demo.dto.ParentPost;
import com.example.demo.model.Grandparent;
import com.example.demo.model.Parent;
import com.example.demo.service.ParentService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("api/v1/grandparents/{grandparent}/parents")
@RequiredArgsConstructor
public class ParentController {
private final ParentService parentService;
@GetMapping
public ResponseEntity<List<Parent>> findBy(@PathVariable long grandparent) {
return ResponseEntity.ok(parentService.findBy(grandparent));
}
@PostMapping
public ResponseEntity<Parent> save(@NonNull @Valid @RequestBody ParentPost parentPost
, @NonNull @PathVariable long grandparent) {
parentPost.setGrandparent(new Grandparent(grandparent, null));
return new ResponseEntity<>(parentService.save(parentPost), HttpStatus.CREATED);
}
}
Children控制器
package com.example.demo.controller;
import com.example.demo.dto.ChildrenPost;
import com.example.demo.model.Children;
import com.example.demo.model.Parent;
import com.example.demo.service.ChildrenService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("api/v1/grandparents/{grandparent}/parents/{parent}/children")
@RequiredArgsConstructor
public class ChildrenController {
private final ChildrenService childrenService;
@GetMapping
public ResponseEntity<List<Children>> findBy(@PathVariable long grandparent) {
return ResponseEntity.ok(childrenService.findBy(grandparent));
}
@PostMapping
public ResponseEntity<Children> save(@NonNull @Valid @RequestBody ChildrenPost childrenPost
, @NonNull @PathVariable long parent) {
childrenPost.setParent(new Parent(parent, null, null));
return new ResponseEntity<>(childrenService.save(childrenPost), HttpStatus.CREATED);
}
}
我是这样解决的:
@PostMapping("{id}/duplicate")
public ResponseEntity<Grandparent> duplicate(@NonNull @PathVariable long id) {
var originGrandparent = grandparentService.findById(id);
var originParentList = parentService.findBy(originGrandparent.get().getId());
var originChildrenList = new ArrayList<Children>();
originParentList.forEach(originParent -> {
List<Children> originChildren = childrenService.findBy(originParent.getId());
originChildrenList.addAll(originChildren);
});
var newGrandparent = new GrandparentPost();
newGrandparent.setName(originGrandparent.get().getName() + " copy");
var savedGrandparent = grandparentService.save(newGrandparent);
var newParent = new ParentPost();
var savedParentList = new ArrayList<Parent>();
originParentList.forEach(originParent -> {
newParent.setGrandparent(new Grandparent(savedGrandparent.getId(), null));
newParent.setName(originParent.getName());
var savedParent = parentService.save(newParent);
savedParentList.add(savedParent);
originChildrenList.forEach(origenChild -> {
if (Objects.equals(origenChild.getParent().getId(), originParent.getId())) {
var newChild = new ChildrenPost();
newChild.setParent(savedParent);
newChild.setName(origenChild.getName());
childrenService.save(newChild);
}
});
});
return ResponseEntity.ok(savedGrandparent);
}
如果有人知道改进此代码的方法,请随时分享。
在我的用例中,我需要创建一个端点,通过将数据从当前记录复制到创建新主键的新记录来复制记录及其相关项。
当前回复: 原始记录
[
{
"id": 1,
"name": "Grandparent One",
"parents": [
{
"id": 1,
"name": "Parent One",
"children": [
{
"id": 1,
"name": "Child One"
},
{
"id": 2,
"name": "Child Two"
}
]
}
]
}
]
预期响应: 原始记录和重复记录
[
{
"id": 1,
"name": "Grandparent One",
"parents": [
{
"id": 1,
"name": "Parent One",
"children": [
{
"id": 1,
"name": "Child One"
},
{
"id": 2,
"name": "Child Two"
}
]
}
]
},
{
"id": 2,
"name": "Grandparent One Copy",
"parents": [
{
"id": 2,
"name": "Parent One",
"children": [
{
"id": 3,
"name": "Child One"
},
{
"id": 4,
"name": "Child Two"
}
]
}
]
}
]
任何人都可以提示我如何在 GrandparentController
中实现此端点吗?
@PostMapping("{id}/duplicate")
public ResponseEntity<Grandparent> duplicate(@NonNull @PathVariable long id) {
//How to implement this endpoint?
return null;
}
我的类:
型号
祖父母
package com.example.demo.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "grandparents")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Grandparent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
Parent
package com.example.demo.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "parents")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "grandparent_id", nullable = false
, foreignKey = @ForeignKey(name = "fk_parents_grandparent1"))
private Grandparent grandparent;
private String name;
}
Children
package com.example.demo.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "children")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Children {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id", nullable = false
, foreignKey = @ForeignKey(name = "fk_children_parent1"))
private Parent parent;
private String name;
}
DTO
祖父母Post
package com.example.demo.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class GrandparentPost {
private String name;
}
ParentPost
package com.example.demo.dto;
import com.example.demo.model.Grandparent;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ParentPost {
private Grandparent grandparent;
private String name;
}
ChildrenPost
package com.example.demo.dto;
import com.example.demo.model.Parent;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ChildrenPost {
private Parent parent;
private String name;
}
祖父母回应
package com.example.demo.dto;
import com.example.demo.model.Grandparent;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
public class GrandparentResponseDto {
private Long id;
private String name;
private List<ParentResponseDto> parents;
public GrandparentResponseDto(Grandparent grandparent) {
this.id = grandparent.getId();
this.name = grandparent.getName();
}
}
Parent响应
package com.example.demo.dto;
import com.example.demo.model.Parent;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
public class ParentResponseDto {
private Long id;
private String name;
private List<ChildrenResponseDto> children;
public ParentResponseDto(Parent parent) {
this.id = parent.getId();
this.name = parent.getName();
}
}
Children响应
package com.example.demo.dto;
import com.example.demo.model.Children;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class ChildrenResponseDto {
private Long id;
private String name;
public ChildrenResponseDto(Children children) {
this.id = children.getId();
this.name = children.getName();
}
}
MAPPERS
GrandparentMapper
package com.example.demo.mapper;
import com.example.demo.dto.GrandparentPost;
import com.example.demo.model.Grandparent;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper(componentModel = "spring")
public abstract class GrandparentMapper {
public static final GrandparentMapper INSTANCE = Mappers.getMapper(GrandparentMapper.class);
public abstract Grandparent toGrandparent(GrandparentPost grandparentPost);
}
ParentMapper
package com.example.demo.mapper;
import com.example.demo.dto.ParentPost;
import com.example.demo.model.Parent;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper(componentModel = "spring")
public abstract class ParentMapper {
public static final ParentMapper INSTANCE = Mappers.getMapper(ParentMapper.class);
public abstract Parent toParent(ParentPost parentPost);
}
ChildrenMapper
package com.example.demo.mapper;
import com.example.demo.dto.ChildrenPost;
import com.example.demo.model.Children;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper(componentModel = "spring")
public abstract class ChildrenMapper {
public static final ChildrenMapper INSTANCE = Mappers.getMapper(ChildrenMapper.class);
public abstract Children toChildren(ChildrenPost childrenPost);
}
存储库
祖父母代表
package com.example.demo.repository;
import com.example.demo.model.Grandparent;
import org.springframework.data.jpa.repository.JpaRepository;
public interface GrandparentRep extends JpaRepository<Grandparent, Long> {
}
Parent代表
package com.example.demo.repository;
import com.example.demo.model.Parent;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface ParentRep extends JpaRepository<Parent, Long> {
List<Parent> findByGrandparent_Id(long grandparent);
}
Children代表
package com.example.demo.repository;
import com.example.demo.model.Children;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface ChildrenRep extends JpaRepository<Children, Long> {
List<Children> findByParent_Id(long parent);
}
服务
祖父母服务
package com.example.demo.service;
import com.example.demo.dto.GrandparentPost;
import com.example.demo.mapper.GrandparentMapper;
import com.example.demo.model.Grandparent;
import com.example.demo.repository.GrandparentRep;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class GrandparentService {
private final GrandparentRep grandparentRep;
public List<Grandparent> findAll() {
return grandparentRep.findAll();
}
public Optional<Grandparent> findById(long id) {
return grandparentRep.findById(id);
}
@Transactional
public Grandparent save(GrandparentPost grandparentPost) {
return grandparentRep.save(GrandparentMapper.INSTANCE.toGrandparent(grandparentPost));
}
}
Parent服务
package com.example.demo.service;
import com.example.demo.dto.ParentPost;
import com.example.demo.mapper.ParentMapper;
import com.example.demo.model.Parent;
import com.example.demo.repository.ParentRep;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@RequiredArgsConstructor
public class ParentService {
private final ParentRep parentRep;
public List<Parent> findBy(long grandparent) {
return parentRep.findByGrandparent_Id(grandparent);
}
@Transactional
public Parent save(ParentPost parentPost) {
return parentRep.save(ParentMapper.INSTANCE.toParent(parentPost));
}
}
Children服务
package com.example.demo.service;
import com.example.demo.dto.ChildrenPost;
import com.example.demo.mapper.ChildrenMapper;
import com.example.demo.model.Children;
import com.example.demo.model.Parent;
import com.example.demo.repository.ChildrenRep;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@RequiredArgsConstructor
public class ChildrenService {
private final ChildrenRep childrenRep;
public List<Children> findBy(long parent) {
return childrenRep.findByParent_Id(parent);
}
@Transactional
public Children save(ChildrenPost childrenPost) {
return childrenRep.save(ChildrenMapper.INSTANCE.toChildren(childrenPost));
}
}
控制器
祖父母控制器
package com.example.demo.controller;
import com.example.demo.dto.ChildrenResponseDto;
import com.example.demo.dto.GrandparentPost;
import com.example.demo.dto.GrandparentResponseDto;
import com.example.demo.dto.ParentResponseDto;
import com.example.demo.model.Grandparent;
import com.example.demo.service.ChildrenService;
import com.example.demo.service.GrandparentService;
import com.example.demo.service.ParentService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@RestController
@RequestMapping("api/v1/grandparents")
@RequiredArgsConstructor
public class GrandparentController {
private final GrandparentService grandparentService;
private final ParentService parentService;
private final ChildrenService childrenService;
@GetMapping
public ResponseEntity<List<Grandparent>> findAll() {
return ResponseEntity.ok(grandparentService.findAll());
}
@GetMapping("/{id}")
public ResponseEntity<Optional<Grandparent>> findById(@NonNull @PathVariable long id) {
return ResponseEntity.ok(grandparentService.findById(id));
}
@GetMapping("/{id}/stats")
public ResponseEntity<List<GrandparentResponseDto>> findByStats (@NonNull @PathVariable long id) {
var grandparentStatsDto = grandparentService.findById(id)
.stream()
.map(GrandparentResponseDto::new)
.collect(Collectors.toList());
//List parents
grandparentStatsDto.forEach(grandparentStatsList -> {
List<ParentResponseDto> parentResponseDto = parentService
.findBy(grandparentStatsList.getId())
.stream().map(ParentResponseDto::new)
.collect(Collectors.toList());
//List children
parentResponseDto.forEach(parentStatsList -> {
List<ChildrenResponseDto> childrenResponseDto = childrenService
.findBy(parentStatsList.getId())
.stream().map(ChildrenResponseDto::new)
.collect(Collectors.toList());
parentStatsList.setChildren(childrenResponseDto);
});
grandparentStatsList.setParents(parentResponseDto);
});
return ResponseEntity.ok(grandparentStatsDto);
}
@PostMapping
public ResponseEntity<Grandparent> save(@NonNull @Valid @RequestBody GrandparentPost grandparentPost) {
return new ResponseEntity<>(grandparentService.save(grandparentPost), HttpStatus.CREATED);
}
@PostMapping("{id}/duplicate")
public ResponseEntity<Grandparent> duplicate(@NonNull @PathVariable long id) {
//How to implement this endpoint?
return null;
}
}
Parent控制器
package com.example.demo.controller;
import com.example.demo.dto.ParentPost;
import com.example.demo.model.Grandparent;
import com.example.demo.model.Parent;
import com.example.demo.service.ParentService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("api/v1/grandparents/{grandparent}/parents")
@RequiredArgsConstructor
public class ParentController {
private final ParentService parentService;
@GetMapping
public ResponseEntity<List<Parent>> findBy(@PathVariable long grandparent) {
return ResponseEntity.ok(parentService.findBy(grandparent));
}
@PostMapping
public ResponseEntity<Parent> save(@NonNull @Valid @RequestBody ParentPost parentPost
, @NonNull @PathVariable long grandparent) {
parentPost.setGrandparent(new Grandparent(grandparent, null));
return new ResponseEntity<>(parentService.save(parentPost), HttpStatus.CREATED);
}
}
Children控制器
package com.example.demo.controller;
import com.example.demo.dto.ChildrenPost;
import com.example.demo.model.Children;
import com.example.demo.model.Parent;
import com.example.demo.service.ChildrenService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("api/v1/grandparents/{grandparent}/parents/{parent}/children")
@RequiredArgsConstructor
public class ChildrenController {
private final ChildrenService childrenService;
@GetMapping
public ResponseEntity<List<Children>> findBy(@PathVariable long grandparent) {
return ResponseEntity.ok(childrenService.findBy(grandparent));
}
@PostMapping
public ResponseEntity<Children> save(@NonNull @Valid @RequestBody ChildrenPost childrenPost
, @NonNull @PathVariable long parent) {
childrenPost.setParent(new Parent(parent, null, null));
return new ResponseEntity<>(childrenService.save(childrenPost), HttpStatus.CREATED);
}
}
我是这样解决的:
@PostMapping("{id}/duplicate")
public ResponseEntity<Grandparent> duplicate(@NonNull @PathVariable long id) {
var originGrandparent = grandparentService.findById(id);
var originParentList = parentService.findBy(originGrandparent.get().getId());
var originChildrenList = new ArrayList<Children>();
originParentList.forEach(originParent -> {
List<Children> originChildren = childrenService.findBy(originParent.getId());
originChildrenList.addAll(originChildren);
});
var newGrandparent = new GrandparentPost();
newGrandparent.setName(originGrandparent.get().getName() + " copy");
var savedGrandparent = grandparentService.save(newGrandparent);
var newParent = new ParentPost();
var savedParentList = new ArrayList<Parent>();
originParentList.forEach(originParent -> {
newParent.setGrandparent(new Grandparent(savedGrandparent.getId(), null));
newParent.setName(originParent.getName());
var savedParent = parentService.save(newParent);
savedParentList.add(savedParent);
originChildrenList.forEach(origenChild -> {
if (Objects.equals(origenChild.getParent().getId(), originParent.getId())) {
var newChild = new ChildrenPost();
newChild.setParent(savedParent);
newChild.setName(origenChild.getName());
childrenService.save(newChild);
}
});
});
return ResponseEntity.ok(savedGrandparent);
}
如果有人知道改进此代码的方法,请随时分享。