JPA自定义对象接收查询结果集

1,743 阅读2分钟

使用过jpa就会知道,我们借住@Query注解进行查询操作时,如果单表查询返回的是一个字段或者一个实体类时,很容易接收查询的结果;但是如果我们进行多表关联查询,查询的字段并不一定都在一个表中,所以就不能用实体类接收了,对于这样查询结果又一下三种方式处理。

用Object[]接收 这种方式显得水平好矬,取值的时候还要通过数组索引去取值,太low了,一堆代码看起来也不好看。如果仅是做一些统计类的查询勉强可以接收。

  1. 用Map<String, Object>接收

这种方式相对来说要比Object[]好,因为map的key就是我们查询的字段名,再取值的时候直接通过get方法取值就行,比较方便,当是相比直接用一个pojo来接收结果,使用起来还是要差一些。如何才能将结果转成自定义的对象呢,网上有一些文章是这样处理的:先有map来接收,再讲map转成json,最后将json解析成自定义得pojo(参见JPA自定义对象接收查询结果集_klayer_cong的博客-CSDN博客)。这样看起来处理过程有点麻烦,但是比较容易理解,确实也转成了自定义的pojo,如果只是一条查询结果这样实现还说的过去,如果查询出的数量很大,将会大大影响性能,这个时候就不太好了。

  1. 用@NamedNativeQuery+@SqlResultSetMapping处理

具体实现如下:

(1)pojo

@NamedNativeQuery(
        name = "querySummary",
        query = " select t2.city_cd as cityCd,t2.city_name as cityName,DATE_FORMAT(t1.create_time,'%Y-%m-%d') as createDate,t1.sale_type as saleType " +
                " from tb_project_sale t2 " +
                " left join tb_project_sale_core t1 on t2.id = t1.id " +
                " where t1.sale_type is not null ",
        resultClass = SummaryDto.class,
        resultSetMapping = "summaryMapping")
@MappedSuperclass
@SqlResultSetMapping(
        name = "summaryMapping",
        classes = @ConstructorResult(
                targetClass = SummaryDto.class,
                columns = {
                        @ColumnResult(name = "cityCd", type = String.class),
                        @ColumnResult(name = "cityName", type = String.class),
                        @ColumnResult(name = "createDate", type = String.class),
                        @ColumnResult(name = "saleType", type = String.class),
                }
        )
)
@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
public class SummaryDto {

    private String cityCd;

    private String cityName;

    private String createDate;

    private String saleType;

}

(2)repository

@Repository
@Transactional
public class SummaryRpt {

    @PersistenceContext
    private EntityManager entityManager;

    public List<SummaryDto> getSummary() {
        return entityManager.createNamedQuery("querySummary")
                .getResultList();
    }

}

(3)测试类

@RunWith(SpringRunner.class
@SpringBootTest
public class SummaryServiceImplTest {

    @Autowired
    private SummaryRpt summaryRpt;

    @Test
    public void test() {
        List<SummaryDto> list = summaryRpt.getSummary();
        return;
    }

}

注意:上文中pojo中的注解都是有用的,不要随意删减

本文参考: my.oschina.net/joryqiao/bl…