如何将本机查询结果映射到POJO?

时间:2019-07-15 16:53:43

标签: hibernate spring-boot jpa spring-data-jpa

我有一个复杂的sql查询,该查询连接7个表并返回110列。我正在尝试使用使用共享实体管理器创建的本机查询。不确定如何将结果集映射到POJO。将每一列映射到结果集对象数组是可行的,但是在代码行方面效率很低。关于如何映射它的任何建议或我可以执行此操作的任何其他方式?

这是我实现的一些伪代码:

Query query = sharedEntityManager.createNativeQuery(
                 " select a.c1, a.c2,.., b.c1, b.c2,.., c.c1, c.c2,...
                   from atab a, btab b, ctab c, ...
                   where condition1, condition2,...");

query.setParameter("param1", param1);

List<Object[]> results = query.getResultList();

List<CustomPojo> retList = new ArrayList<>();
for(Object[] obj : results){
  CustomPojo row = new CustomPojo();
  row.setF1(obj[0].toString());
  row.setF2(obj[1].toString());
  ...
  ...
  retList.add(row);
}
return retList;

2 个答案:

答案 0 :(得分:0)

如果您使用Spring Data JPA(并且可以假设是因为您添加了该标签),那么只需将查询添加到您的Repository接口之一即可:

user_id

Spring Data JPA将完成其余的工作。 (您可以通过名称来查询查询中的参数:userUrlspublic interface WhateverRepository extends JpaRepository<...,...> ... @Query(SELECT NEW com.yourcompany...YourPOJO a.c1, a.c2,.., b.c1, b.c2,.., c.c1, c.c2,... from atab a, btab b, ctab c, ... where condition1, condition2,...") YourPOJO callFancyQuery( arg1, arg2, ...); 等)

答案 1 :(得分:0)

您可以轻松地将Projections与DTO结合使用,而不是DTO,例如,在Spring Data JPA中使用本地查询

@Entity
@Table(name = "models")
public class Model {

    @Id
    @GeneratedValue
    private Integer id;

    @Column(length = 32)
    private String name;
}

投影:

public interface NameOnly {
     String getName();
}

回购:

public interface ModelRepo extends JpaRepository<Model, Integer> {
    @Query(value = "select m.name as name from models m", nativeQuery = true)
    List<NameOnly> getAll();
}

(请注意需要在查询m.name as name中使用别名。)

如果您确实需要DTO,则可以创建一个映射器(我相信最好用MapStruct生成它):

@Data
public class ModelDto {
    private String name;
}

@Mapper(componentModel = "spring")
public interface ModelMapper {
    ModelDto toDto(NameOnly nameOnly);
}

然后使用类似的内容:

@Autowired private ModelRepo repo;
@Autowired private ModelMapper mapper;
// ...
repo.getAll()
    .stream()
    .map(mapper::toDto)
    .forEach(System.out::println);