gpt4 book ai didi

grails - GORM-将3个查询更改为1个(或至少2个)

转载 作者:行者123 更新时间:2023-12-02 15:53:12 26 4
gpt4 key购买 nike

我有这样的实体,使用GORM存储在数据库中(我省略了无关字段):

class Payment {
static hasMany = [paymentEntries: PaymentEntry]
}

class PaymentEntry {
static hasOne = [category: PaymentCategory]
static belongsTo = [payment: Payment]
static constraints = {
category(nullable: true)
}
}

class PaymentCategory {
static hasMany = [payments: PaymentEntry, rules: PaymentRule]
String name
}

因此,我们在顶部有Payments,可以有许多PaymentEntryies,每个PaymentEntry可以属于一个PaymentCategory。

我需要选择满足某些条件的“付款”,但仅选择那些还具有属于特定类别的PaymentEntries的条件。目前,我在3个查询中执行此操作:
  • 选择适合部分类别名称的类别,或者仅忽略类别查询(在这种情况下,我们希望所有付款都与条目类别无关):
    private static List<PaymentCategory> getCategories(String category) {
    def result = null
    if (category != null && category.length() > 0) {
    def c = PaymentCategory.createCriteria()

    result = c {
    ilike("name", "%${category}%")
    }
    }

    result
    }
  • 根据PaymentCategory选择PaymentEntries ID:
    private static List<Long> paymentEntryIds(String category) {
    def categories = getCategories(category)
    def c = PaymentEntry.createCriteria()

    def result = new ArrayList()

    // If category is selected, but there is no matching category, return empty list
    if (!categorySelectedButNoMatch(category, categories)) {
    result = c {
    if (category == null) {
    isNull("category")
    } else if (categories != null && categories.size() > 0) {
    inList("category", categories)
    }

    projections {
    property("id")
    }
    }
    }

    result
    }
  • 最后选择Payments,仅限包含特定PaymentEntries的付款:
    def paymentEntriesIds = paymentEntryIds(selectedCategory)

    def c = Payment.createCriteria()

    def result = new ArrayList()

    // If there are no payment entries matching category criteria, we return empty list anyway, so there
    // is no need querying payments.
    if (paymentEntriesIds.size() > 0) {
    result = c {
    paymentEntries {
    inList("id", paymentEntriesIds)
    }

    if (importEntryId != null) {
    eq("importEntry.id", importEntryId)
    }
    if (query != null) {
    ilike("description", query)
    }
    // Omitted ordering and paging
    }
    }

    result

  • 该方法有效,但是它对数据库运行3个查询。我很确定此代码可以更简洁,并且可以在更少的查询中完成。欢迎提出所有关于如何改进它的想法。

    最佳答案

    您可以至少使用3种不同的方法:分离查询,HQL where子查询和HQL子查询。

    具有条件的DetachedQuery示例如下所示:

    def subquery = new DetachedCriteria(PaymentCategory).build {        
    projections {
    groupProperty 'id'
    }

    ilike("name", "%${category}%")
    }

    然后,您可以在另一个查询中使用此子查询:
    return PaymentEntry.createCriteria().list {        
    category {
    inList "id", subquery
    }
    }

    我没有在您的域上进行准确的测试,这仅表明了这一想法。请参阅GORM文档的DetachedCriteria部分: https://grails.github.io/grails-doc/latest/guide/single.html#detachedCriteria

    我们将其用于一些非常复杂的查询。有时需要 createAlias才能正确使用关联。

    关于grails - GORM-将3个查询更改为1个(或至少2个),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36233982/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com