【问题标题】:How to set columns from a joined entity in JPAQuery and Querydsl如何在 JPAQuery 和 Querydsl 中设置连接实体的列
【发布时间】:2020-06-24 06:44:26
【问题描述】:

我正在使用一个现有软件进行国际化。作为其中的一部分,我有一个表格,简化为最简单的情况是:

ID AUTONUMERIC
ID_OF_TEXT NUMBER
TEXT VARCHAR

必须将文本列翻译成新语言(可能存在也可能不存在)。所以有另一个带有列的新表:

ID_OF_TEXT NUMBER
LANGUAGE_CODE VARCHAR
TRANSLATED_TEXT VARCHAR

已经有一个实体来表示基表,这个实体不能改变。它生成的代码如下:

class QMyBaseEntity extends EntityPathBase<MyBaseEntity> {
    NumberPath<Long> id = createNumber("id", Long.class);
    NumberPath<Long> toTranslateId = createNumber("toTranslateId", Long.class);
    StringPath text = createString("text");
}

为翻译查找表生成的代码如下所示:

@Generated("com.mysema.query.codegen.EntitySerializer")
class QTranslationLookup extends EntityPathBase<TranslationLookup> {
    NumberPath<Long> id = createNumber("id", Long.class);
    NumberPath<Long> translationId = createNumber("translationId", Long.class);
    StringPath languageCode = createString("languageCode");
    StringPath translated_text = createString("translated_text");
}

我希望MyBaseEntity 的字段text 采用转换表的值(如果存在)而不是其原始值。已经有一个非常复杂的查询,除了添加如下连接之外我无法更改:

String languageCode = "de";
JPAQuery query = new JPAQuery(entityManager);
query.from(qMyBaseEntity);
// add lots of other joins and stuff here
query.leftJoin(qTranslationLookup)
        .on(qTranslationLookup.translationId.eq(qMyBaseEntity.toTranslateId)
        .and(qTranslationLookup.languageCode.eq(languageCode)));
List<MyBaseEntity> results = query.list(qMyBaseEntity);

在对现有代码进行最小更改的情况下,如何设置 results 列表中的翻译值,以便返回的实体实例包含 text 列中的翻译,而不是来自旧的(未翻译的)表?

【问题讨论】:

    标签: java jpa querydsl


    【解决方案1】:

    Mysema 不是框架,QueryDSL 是。 QueryDSL 曾经由 Mysema 开发,但现在不再是,并且该软件包已移至 com.querydsl 组 ID。

    您不能覆盖实体投影中托管属性的值。这些值将始终是实体的实际字段值。实体不能用作 DTO。如果要投影不同种类的表达式,则需要使用元组投影。

    List<Tuple> results = query.from(qMyBaseEntity)
        .leftJoin(qTranslationLookup)
        .on(qTranslationLookup.translationId.eq(qMyBaseEntity.toTranslateId)
        .and(qTranslationLookup.languageCode.eq(languageCode)))
        .select(qMyBaseEntity, qTranslationLookup.translatedText.coalesce(qMyBaseEntity.text))
        .fetch()
    

    或者,例如,您可以返回一个映射:

    Map<MyBaseEntity, String> results = query.from(qMyBaseEntity)
        .leftJoin(qTranslationLookup)
        .on(qTranslationLookup.translationId.eq(qMyBaseEntity.toTranslateId)
        .and(qTranslationLookup.languageCode.eq(languageCode)))
        .transform(GroupBy.groupBy(qMyBaseEntity).as(
             qTranslationLookup.translatedText.coalesce(qMyBaseEntity.text))
        .fetch()
    

    或者您可以使用 QueryDSL 的 DTO 投影:

    List<ResultDTO> results = query.from(qMyBaseEntity)
        .leftJoin(qTranslationLookup)
        .on(qTranslationLookup.translationId.eq(qMyBaseEntity.toTranslateId)
        .and(qTranslationLookup.languageCode.eq(languageCode)))
        .select(Projections.constructor(ResultDTO.class, qMyBaseEntity, qTranslationLookup.translatedText.coalesce(qMyBaseEntity.text))
        .fetch()
    

    【讨论】:

      猜你喜欢
      • 2019-06-02
      • 2016-03-28
      • 2015-04-27
      • 2018-10-24
      • 1970-01-01
      • 2014-09-12
      • 2016-01-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多