当前位置: 首页 > 知识库问答 >
问题:

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

澹台景山
2023-03-14

我正在使用查询与Spring数据jpa。我已经实现了自定义存储库来查找人名。人员实体如下所示:

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

那么我想选“约翰·斯诺先生”。有什么办法可以做到吗?

我不想选择整个记录来连接值,因为实体有其他列和许多关联,加载整个记录不好。

共有2个答案

奚昌胤
2023-03-14

使用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();
归建安
2023-03-14

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

当我们只需要很少的列信息而不需要创建新的d to时,这是非常有用的。

 类似资料:
  • 问题内容: 给定以下示例表架构 客户表 发票表 目的是选择InvoiceID值为10和20(非OR)的所有客户。因此,在此示例中,将返回带有CustID = 1和2的客户。 您将如何构造SELECT语句? 问题答案: 使用: 关键是需要计数等于子句中参数的数量。 的使用是在对帐务编号和发票编号的组合没有唯一约束的情况下- 如果没有重复的机会,则可以从查询中省略DISTINCT:

  • 问题内容: 如何选择多个表并从同一列联接多个行? 它不会返回,并且。我确定此SQL代码段的语法错误。 更新: 显示。移除后 它返回: 但我需要退货: 问题答案: 您可以多次连接到同一张表,而只需提供不同的别名

  • 问题内容: 编辑: 直到这里,我得到适当的4行,但它们都是相同的结果(我知道我需要4行,但是有不同的结果) 我的问题是,如何仅通过LotteryOfferId来通过多对多表检索所有彩票? 我要实现的是通过LotteryDrawDateId从彩票表中获取数据。 首先,我使用LotteryOfferId从中间表获取DrawDates,然后通过中间表获取drawDateIds以在LotteryDrawD

  • 假设我有两个表和。包含和列。有两列和,它们链接回的列。

  • 其目的是从联接的表(多对多)中选择列。 我遇到的问题是从联接的多对多表中选择两列。 我使用的是SpringBoot2.3和Spring data JPA。 我有这个数据模型,我想要获取的是蓝色装箱的字段

  • > 帐户表:accountId(PK)电子邮件密码 account_profile表:accountId(PK)(fk到account)昵称 团体表:articleId(PK)accountId(fk to account)标题内容 现在我想要下面的JPQL是查询DSL代码 我有实体元模型-QAccount、QAccountProfile、QCommunity 此外,我必须通过分页获得结果,因此应