簡體   English   中英

Querydsl-如何在選擇表達式中連接多個列的值?

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

我正在使用帶有彈簧數據jpa的Querydsl。 我已經實現了自定義存儲庫以查找人員姓名。 人員實體如下所示:

@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
}

實現的自定義存儲庫:

@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();
    }
}

在選擇表達式中,我想加入三列以構造全名。 如果數據庫具有類似以下的記錄-

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

那么我想選擇“ John Snow先生”。 有什么辦法嗎?

我不想選擇整個記錄來連接該值,因為實體具有其他列和很多關聯,並且加載整個記錄不是很好。

您可以使用3.2.3僅選擇所需的3列 Querydsl文檔中的構造函數用法

這樣,您將需要以編程方式將它們加入,但是您將只能選擇所需的3列。

創建一個僅包含所需字段的類。

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;
    }
}

然后您可以創建查詢

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

@ chris-sekas提供了一個很好的解決方案,但這是另一個似乎很方便的解決方案。 我使用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());

當我們只需要很少的列信息並且不需要創建新的DTO時,這將非常有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM