简体   繁体   English

map 是否可以使用嵌套的 select 语句对 DTO 进行查询?

[英]Is it possibe to map a query with nested select statements to a DTO?

I have a query with nested select我有一个嵌套 select 的查询

Query query = manager.createQuery("Select a, (Select b from some_table where condition)....");

There is a DTO Class有一个 DTO Class

public class Result
{
private int a;
private int b;

//getters and setters
}

The method of new packageName.Result(a,b) in the query wont work here because of nested select, so what can be done here?由于嵌套了 select,查询中 new packageName.Result(a,b) 的方法在这里不起作用,那么这里可以做什么呢? Thanks in advance提前致谢

The JPQL constructor expression is really just syntax sugar, so you could just as well transform the resulting list afterwards. JPQL 构造函数表达式实际上只是语法糖,因此您也可以在之后转换结果列表。

TypedQuery<Object[]> query = manager.createQuery("Select a, (Select b from some_table where condition)....", Object[].class);
List<Object[]> list = query.getResultList();
list.stream().map(array -> new Result((int) array[0], (int) array[1])).collect(toList())

I think this is a perfect use case forBlaze-Persistence Entity Views , especially if you have the need for more complex or nested DTOs.我认为这是Blaze-Persistence Entity Views的完美用例,尤其是当您需要更复杂或嵌套的 DTO 时。

I created the library to allow easy mapping between JPA models and custom interface or abstract class defined models, something like Spring Data Projections on steroids.我创建了该库以允许在 JPA 模型和自定义接口或抽象 class 定义的模型之间轻松映射,例如 Spring 类固醇上的数据投影。 The idea is that you define your target structure(domain model) the way you like and map attributes(getters) via JPQL expressions to the entity model.这个想法是您以您喜欢的方式定义您的目标结构(域模型),并通过 JPQL 表达式将 map 属性(吸气剂)定义为实体 model。

A DTO model for your use case could look like the following with Blaze-Persistence Entity-Views:使用 Blaze-Persistence Entity-Views 的 DTO model 可能如下所示:

@EntityView(MainEntity.class)
public interface Result {
    int getA();
    @MappingSubquery(MySubqueryProvider.class)
    int getB();

    class MySubqueryProvider implements SubqueryProvider {
        @Override
        public <T> T createSubquery(SubqueryInitiator<T> subqueryBuilder) {
            return subqueryBuilder.from(SubEntity.class, "subEntity")
                       .select("subEntity.b")
                       .where("subEntity.c").eqExpression("OUTER(c)")
                   .end();
        }
    }
}

Which will create the subquery just as you expect it.它将按照您的预期创建子查询。 Depending on your subquery, you could also use this simpler variant根据您的子查询,您还可以使用这个更简单的变体

@EntityView(MainEntity.class)
public interface Result {
    int getA();
    @Mapping("SubEntity[c = VIEW(c)].b")
    int getB();
}

Which will produce a left join query like this:这将产生一个左连接查询,如下所示:

select e.a, s.b
from MainEntity e
left join SubEntity b on b.c = e.c

Querying is a matter of applying the entity view to a query, the simplest being just a query by id.查询是将实体视图应用于查询的问题,最简单的就是通过 id 进行查询。

Result a = entityViewManager.find(entityManager, Result.class, id);

The Spring Data integration allows you to use it almost like Spring Data Projections: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features Spring 数据集成允许您几乎像 Spring 数据投影一样使用它: https://persistence.blazebit.com/documentation/entity-view/manual-html/

Page<Result> findAll(Pageable pageable);

The best part is, it will only fetch the state that is actually necessary!最好的部分是,它只会获取实际需要的 state!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM