【问题标题】:Grails i18n. Query domain class and translation with one SQL select圣杯 i18n。一键查询域类和翻译
【发布时间】:2013-11-12 11:51:22
【问题描述】:

我正在构建一个 Grails 应用程序,其中包含用户可以以多种语言输入的数据。英语被认为是未找到翻译时显示的默认语言。在这个网站上浏览了一下之后,我最终得到了以下域类。

class SomeData {
    String name            // Default English name
    String description     // Default English description
    int otherData
    double moreData
    ....
    SomeDataTranslation translation
    static transients = ['translation']
    static hasMany = [translations: SomeDataTranslation]

    def getName() {
        if (translation) return translation.name
        return name
    }
}

class SomeDataTranslation {
    String languageCode
    String name            // Name in some other language
    String description     // Description in some other language
    static belongsTo = [data: SomeData]
}

我正在尝试对其进行设置,以便理想情况下使用一条 SQL 语句对其进行查询。那么如何使用 GORM 填充瞬态“翻译”成员变量?基本用例是我需要将 SomeData 实例列表作为 JSON 返回,并使用已翻译的文本(如果存在)。所以我希望能够做一个简单的查询,如果存在所请求语言的翻译,则返回 SomeData 实例,其中设置了“翻译”成员变量。

我摸索了派生属性,但得出的结论是派生属性只能从其他属性派生。我无法使用语言代码请求参数。

编辑

根据 Sérgio Michels 的建议,我一直在尝试使用 HQL 来做到这一点,而且我非常接近,但还没有。这是我目前所拥有的:

def query = 'select sd,dt from SomeData as sd, SomeDataTranslation as sdt
             where sd.name like ? and sdt.data = sd and sdt.languageCode = ?'
def queryParams =["something%", "es"]
def result = SomeData.executeQuery(query, queryParams, [readOnly: true])

def dataList = []
result.each {
    it[0].translation = it[1]
    SomeData someData = it[0]
    someData.translation = it[1]  // Fill the transient 'translation' property
    dataList << someData
}

我遇到的问题是“where”子句过滤掉了根本没有翻译的 SomeData 实例。我正在使用左连接来确保查询返回所有带有搜索字符串“某物”的 SomeData 实例,并且当不存在翻译时,我希望“翻译”属性为空。如果我删除 'sdt.languageCode = ?'过滤器,我得到所有语言的所有翻译。那么如何在保留空值的同时过滤所需的语言呢?

【问题讨论】:

    标签: sql grails internationalization grails-orm


    【解决方案1】:

    您可以使用executeQuery 在一个查询中同时返回SomeDataSomeDataTranslation。这将返回一个数组给您,然后您需要手动分配翻译。

    SomeData getSomeData() {
    
      def result = SomeData.executeQuery(' from SomeData sd, SomeDataTranslation sdt where sdt.data = sd', [max: 1])
    
      println result //[SomeData , SomeDataTranslation]
    
      SomeData sd = result[0]
      sd.translation = result[1]
    
      return sd
    }
    

    值得一提的是,它使用Hibernate's HQL syntax 来构建查询。

    【讨论】:

    • 谢谢,我试试看。不幸的是,我只是尝试升级到 grails 2.3.2,它像往常一样破坏了构建。如今,每次升级似乎都会发生这种情况。我将尝试恢复到 2.3.1 以进行尝试。
    • 我现在有时间看看这个。 executeQuery() 返回单个 SomeData 实例,但我需要使用一些条件查询它们的列表,并且我正在寻找一种方法来填充所有这些实例的“翻译”属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-06
    • 2015-08-20
    • 2011-10-11
    • 1970-01-01
    • 2012-08-12
    相关资源
    最近更新 更多