简体   繁体   English

Querydsl-如何在选择表达式中连接多个列的值?

[英]Querydsl - How to join multiple column's value in select expression?

I'm using Querydsl with spring data jpa. 我正在使用带有弹簧数据jpa的Querydsl。 I've implemented custom repository to find out person names. 我已经实现了自定义存储库以查找人员姓名。 The person entity looks like as follows: 人员实体如下所示:

@Entity
@Table(name = "persons")
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false, updatable = false)
    private Long id;

    @Column(name = "initial")
    private String initial;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "archived")
    private Boolean archived;

    //Other columns here.. && Getter setter goes here
}

The implemented custom repository: 实现的自定义存储库:

@Repository
public class PersonRepositoryImpl extends QueryDslRepositorySupport 
        implements PersonRepositoryCustom {
    public PersonRepositoryImpl() {
        super(Person.class);
    }

    @Override
    public List<String> getPersonNames() {
        return getQuerydsl()
                .createQuery()
                .from(QPerson.person)
                .where(QPerson.person.archived.eq(Boolean.FALSE))
                .select(/* 
                    want to select as a full name like
                    initial + firstName + lastName
                  */)
                .fetch();
    }
}

In the select expression, I would like to join three columns to construct full name. 在选择表达式中,我想加入三列以构造全名。 If database has a record like the following - 如果数据库具有类似以下的记录-

id | initial | firstName | lastName | archived | ...
----------------------------------------------------
1  | "Mr"    | "John"    | "Snow"   | 0        | ...

then I would like to select as "Mr John Snow". 那么我想选择“ John Snow先生”。 Is there any way to do that? 有什么办法吗?

I don't want to select whole record to concat the value because entity has others column and lots of associations and it's not good to load whole record. 我不想选择整个记录来连接该值,因为实体具有其他列和很多关联,并且加载整个记录不是很好。

You can select only the 3 columns you need by using 3.2.3. 您可以使用3.2.3仅选择所需的3列 Constructor usage from Querydsl documentation. Querydsl文档中的构造函数用法

This way you will need to join them programmatically, but you will achieve to select only the 3 columns you need. 这样,您将需要以编程方式将它们加入,但是您将只能选择所需的3列。

Create a class that has only the fields you need. 创建一个仅包含所需字段的类。

public class PersonDTO {
    private String initial;
    private String firstName;
    private String lastName;

    public PersonDTO(String initial, String firstName, String lastName) {
        this.initial = initial;
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

Then you can create the query 然后您可以创建查询

           query.from(QPerson.person)
                .select(Projections.constructor( 
                        PersonDTO.class, 
                        QPerson.person.initial, 
                        QPerson.person.firstName, 
                        QPerson.person.lastName))
                .fetch();

@chris-sekas provide a good solution, but here is another one that seems to be very handy. @ chris-sekas提供了一个很好的解决方案,但这是另一个似乎很方便的解决方案。 I've used com.querydsl.core.Tuple instead of creating new DTO. 我使用com.querydsl.core.Tuple而不是创建新的DTO。

QPerson person = QPerson.person;
List<Tuple> tuples = getQuerydsl()
        .createQuery()
        .from(person)
        .where(person.archived.eq(Boolean.FALSE))
        .select(person.initial, 
                person.firstName,
                person.lastName)
        .fetch();

List<String> names = tuples.stream()
        .map(t ->
                t.get(person.initial) +
                " " +
                t.get(person.firstName) +
                " " +
                t.get(person.lastName))
        .distinct()
        .collect(Collectors.toList());

It's very useful when we need few column's information only and don't need to create new DTO. 当我们只需要很少的列信息并且不需要创建新的DTO时,这将非常有用。

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

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