如何实现基于persCod查询Property并关联Paper信息的GET响应?
问题求助:Spring Boot 多实体关联查询接口实现
实体结构与业务需求
现有三个数据库实体:
- Person实体:主键为
persCod - Paper实体:主键为
serialNumber - Property实体:以
persCod和serialNumber作为复合主键
业务逻辑:单个Person可拥有多个Property,每个Property对应一份Paper。
需要实现:当发送GET请求至localhost:8080/property/{persCodA}时,响应体返回该Person对应的所有Property信息,同时包含与Property的serialNumber匹配的Paper的paperName。
实体代码
Person实体
@Data @Entity @Table(name = "PERSON") @NoArgsConstructor @AllArgsConstructor public class Person{ @Id private Long persCod; private String name; }
Paper实体
@Data @Entity @Table(name = "PAPERS") @NoArgsConstructor @AllArgsConstructor public class Paper{ @Id private Integer serialNumber; private String paperName; }
Property实体
@Data @Entity @Table(name = "PROPERTY") @IdClass(IdProperty.class) @NoArgsConstructor @AllArgsConstructor public class Property { @Id private Long persCod; @Id private Integer serialNumber; private String paperName; private String description; }
期望响应格式
[ { "serialNumber": 101010, "paperName": "[与serialNumber=101010匹配的Paper名称]", "description": "对应描述" }, { "serialNumber": 30303, "paperName": "[与serialNumber=30303匹配的Paper名称]", "description": "对应描述" } ]
解决方案步骤
1. 修正Property实体关联关系
Property中的paperName属于冗余字段,应通过关联Paper实体动态获取,修改后的Property实体如下:
@Data @Entity @Table(name = "PROPERTY") @IdClass(IdProperty.class) @NoArgsConstructor @AllArgsConstructor public class Property { @Id private Long persCod; @Id private Integer serialNumber; // 通过serialNumber关联Paper实体,insertable/updatable=false避免主键字段重复维护 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "serialNumber", insertable = false, updatable = false) private Paper paper; private String description; }
2. 创建响应DTO类
为了精准匹配期望的响应格式,定义专用的DTO类:
@Data @NoArgsConstructor @AllArgsConstructor public class PropertyResponseDTO { private Integer serialNumber; private String paperName; private String description; }
3. 编写Repository查询逻辑
使用JPQL实现关联查询,直接返回DTO结果:
public interface PropertyRepository extends JpaRepository<Property, IdProperty> { @Query("SELECT new com.yourpackage.dto.PropertyResponseDTO(p.serialNumber, pa.paperName, p.description) " + "FROM Property p JOIN p.paper pa WHERE p.persCod = :persCod") List<PropertyResponseDTO> findByPersCod(Long persCod); }
注意替换com.yourpackage.dto为实际项目中的DTO包路径。
4. 实现Controller接口
编写REST接口处理GET请求:
@RestController @RequestMapping("/property") public class PropertyController { private final PropertyRepository propertyRepository; // 构造方法注入(推荐替代@Autowired) public PropertyController(PropertyRepository propertyRepository) { this.propertyRepository = propertyRepository; } @GetMapping("/{persCodA}") public List<PropertyResponseDTO> getPropertiesByPerson(@PathVariable Long persCodA) { return propertyRepository.findByPersCod(persCodA); } }
5. 完善复合主键类
确保IdProperty类正确实现Serializable接口:
@Data @NoArgsConstructor @AllArgsConstructor public class IdProperty implements Serializable { private Long persCod; private Integer serialNumber; }
内容的提问来源于stack exchange,提问作者gustop01
相关产品推荐
相关产品推荐

