【问题标题】:createCriteria()创建标准()
【发布时间】:2013-01-28 20:49:20
【问题描述】:

我正在尝试创建一个以 JSON 格式返回结果的 REST 服务。

我创建了一个返回搜索结果的方法。它接受搜索参数的 EnumMap,并根据这些参数进行检查以构建 createCriteria。

我遇到的问题是 validFor 适用于 tradingName 的有效期,无论当前日期/时间是否在“有效期”期间或不是。

在返回 JSON 的示例中,它应该只带回names 中的第一个,因为其他两个validFor 不在startend 范围内

findCentre 方法

def findCentre(EnumMap searchParams) {

    def c = Centre.createCriteria()
    def results = c.listDistinct {
        if(searchParams.containsKey(CENTRE_SEARCH_PARAMETERS.START_CENTRE_CODE_RANGE) && searchParams.containsKey(CENTRE_SEARCH_PARAMETERS.END_CENTRE_CODE_RANGE)) {
            between("code", searchParams.get(CENTRE_SEARCH_PARAMETERS.START_CENTRE_CODE_RANGE), searchParams.get(CENTRE_SEARCH_PARAMETERS.END_CENTRE_CODE_RANGE))
        }

        if(searchParams.containsKey(CENTRE_SEARCH_PARAMETERS.CENTRE_CODE_PARTIAL)) {
            like("code", "%" + searchParams.get(CENTRE_SEARCH_PARAMETERS.CENTRE_CODE_PARTIAL) + "%")
        }

        if(searchParams.containsKey(CENTRE_SEARCH_PARAMETERS.INDIVIDUAL_CENTRE_CODE)) {
            eq("code", searchParams.get(CENTRE_SEARCH_PARAMETERS.INDIVIDUAL_CENTRE_CODE))
        }

        if(searchParams.containsKey(CENTRE_SEARCH_PARAMETERS.CENTRE_NAME_PARTIAL)) {
            names {
                ilike("tradingName", "%" + searchParams.get(CENTRE_SEARCH_PARAMETERS.CENTRE_NAME_PARTIAL) + "%")
                validFor {
                    and {
                        le("start", new Date())
                        ge("end", new Date())
                    }
                }
            }
        }
    }
    results
}

我返回的 JSON 响应如下所示

[
{
    "code": "1",
    "names": [
        {
            "trading_name": "ABC",
            "valid_time": {
                "start": "2013-02-13T08:54:31Z",
                "end": "2018-02-12T08:54:31Z"
            }
        },
        {
            "trading_name": "ABCDEF",
            "valid_time": {
                "start": "2013-03-31T23:00:00Z",
                "end": "2013-12-31T00:00:00Z"
            }
        },
        {
            "trading_name": "DEF",
            "valid_time": {
                "start": "2013-03-31T23:00:00Z",
                "end": "2013-12-31T00:00:00Z"
            }
        }
    ],
    "email": "blah@blah.com"
}
]

我认为问题出在findCentre 方法中,但我目前缺乏 Grails 经验导致我遇到挫折。您能给我的任何帮助将不胜感激。

【问题讨论】:

    标签: json hibernate grails criteria


    【解决方案1】:

    您返回的结果是完整的 Centre 对象 - 您将搜索限制为那些 当前 名称与模式匹配的对象,但随后返回所有已知匹配对象的名称无论日期如何。

    最简单的方法可能是对条件结果进行后过滤,而不是直接返回它们

    Date now = new Date()
    return results.collect { res ->
      [code: res.code,
       names: res.names.findAll { it.start <= now && it.end >= now }*.tradingName,
       email: res.email ]
    }
    

    应该会给你类似 JSON 的

    [
      {"code":"1",
       "names":["ABC"],
       "email": "blah@blah.com"
      }
    ]
    

    【讨论】:

    • 谢谢伊恩。那效果很好。我知道它正在返回整个 Centre 对象,但我认为 createCriteria() 的 validFor { and { le("start", new Date()) ge("end", new Date()) } } 部分会过滤正确的结果。请你能再解释一下吗?抱歉,对 Grails 完全陌生。
    • @GarethLewis 条件查询中的条件只是限制从数据库中选择哪些对象的一种方式,但每个选择的对象都会完整返回 - 在 SQL 术语中,它们是 WHERE 子句,但不要'不影响选择的内容。您可以使用 projections 块来定义 SELECT,但我无法想出一种方法来完成您需要的投影,这就是我建议后过滤的原因。
    • 再次感谢。我明白你在说什么。将查看projections 以获取信息。
    猜你喜欢
    • 1970-01-01
    • 2018-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    • 2021-09-22
    • 1970-01-01
    相关资源
    最近更新 更多