如何在Spring Boot JPA查询中用Lombok @Builder实现自定义构造查询
在Spring Boot JPA查询中使用Lombok @Builder创建自定义构造方法的正确方式
你当前的JPQL写法存在问题——JPQL是面向实体的查询语言,无法直接调用Java类的builder()方法,可以采用以下两种可行方案:
方案一:构造器表达式配合@Builder
- 给
SolicitudResponse同时添加@Builder和@AllArgsConstructor注解(Lombok会自动生成全参构造器和builder模式代码):
import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @Getter @Builder @AllArgsConstructor public class SolicitudResponse { private String identificacion; // 其他业务字段... }
- 修改JPQL查询,使用构造器表达式直接返回DTO:
@Query("select new com.multiplos.cuentas.pojo.solicitud.SolicitudResponse(s.inversionista.persona.identificacion) from Solicitud s") List<SolicitudResponse> findSolicitudResponses();
这种方式下,JPA会通过全参构造器实例化SolicitudResponse,同时你依然可以在业务代码里用SolicitudResponse.builder()的方式手动创建对象。
方案二:接口投影+Builder转换
如果DTO字段较多,或者不想依赖全参构造器,可以用接口投影先获取数据,再转换为Builder构建的DTO:
- 定义投影接口,包含需要获取的属性对应的getter方法:
public interface SolicitudProjection { String getIdentificacion(); // 其他需要的属性对应的getter方法... }
- 编写JPA查询返回投影结果:
@Query("select s.inversionista.persona.identificacion as identificacion from Solicitud s") List<SolicitudProjection> findSolicitudProjections();
- 在业务层将投影转换为
SolicitudResponse(用Builder模式):
List<SolicitudResponse> responses = solicitudRepository.findSolicitudProjections() .stream() .map(projection -> SolicitudResponse.builder() .identificacion(projection.getIdentificacion()) // 其他字段赋值... .build()) .collect(Collectors.toList());
注意事项
- 确保
SolicitudResponse上的@Builder注解生效,同时添加@Getter等注解保证字段可访问; - 使用构造器表达式时,JPQL中select的字段顺序必须和全参构造器的参数顺序、类型完全匹配;
- 接口投影的getter方法名必须和JPQL中指定的别名(或实体属性名)对应,比如
getIdentificacion()对应identificacion字段。
内容的提问来源于stack exchange,提问作者David Macias
相关产品推荐
相关产品推荐

