GORM 批量获取和更新

GORM fetch and update in batches

我需要使用 grails 2.5

更新 Oracle 数据库中大量数据的单个 属性

现在我的代码看起来与此类似:

    List booksToUpdate = []
    boolean moreBooks = true
    int offset = 0

    while (moreBooks) {
        def fetchedBooks = []
        if('Europe'){
            fetchedBooks = Book.findAllByAuthorInList(getEuropeanAuthors(),
                    [max: BATCHSIZE, offset: offset])
        } else {
            fetchedBooks = Book.findAllByAuthorInListAndPublishYear(getEnglishAuthors(), '1999',
                    [max: BATCHSIZE, offset: offset])
        }

        booksToUpdate.addAll(fetchedBooks)

        moreBooks = fetchedBooks.size() == BATCHSIZE
        offset += BATCHSIZE
    }

    booksToUpdate.each { book ->
        book.copyright = '2020'
        book.save(flush: true, failOnError: true)
    }

我想批量更新我的性能。此外,findAll 查询略有不同,有条件地构建搜索条件会很好。理想情况下,我想要这样的东西:

    while (moreBooks) {
        def fetchedBooks = []

        def criteria = new DetachedCriteria(Book)
        criteria.build [max: BATCHSIZE, offset: offset] {
            List relevantAuthors = []
            if('Europe') {
                relevantAuthors = getEuropeanAuthors()
                eq 'publishYear', '1999'
            } else {
                relevantAuthors = getEnglishAuthors()
            }
            inList 'author', relevantAuthors
        }
        criteria.updateAll(copyright:'2020') //batch update

        moreBooks = fetchedBooks.size() == BATCHSIZE
        offset += BATCHSIZE
    }

有办法吗?不必与 DetachedCriteria 一起使用。我查看了 guide 但我找不到任何关于传递最大值和偏移量的信息。有没有更好的方法可以在不影响性能的情况下让代码更优雅?

updateAll 更新所有内容,即使设置了默认 maxoffset。 我意识到我需要取回更新实例的列表。因此,试图将所有内容都强制为一个 updateAll 而 returns 只有 count 是没有意义的。 结束于此:

List updateCopyright(String geo) {
    DetachedCriteria<Book> findCr = getQueryFromGeo(geo)
    
    List<String> updatedBookIds = []
    boolean moreBooks = true
    int offset = 0
    
    while (moreBooks) {
        List<Book> fetchedBooks = findCr.list([max: BATCHSIZE, offset: offset])
        List currentBatchIds = fetchedBooks*.id

        def updateCr = Book.where {
            inList 'id', currentBatchIds
        }
        int updatedCount = updateCr.updateAll(copyright: '2020')

        moreBooks = updatedCount == BATCHSIZE
        offset += BATCHSIZE

        updatedBookIds.addAll(currentBatchIds)
    }

    updatedBookIds
}


private DetachedCriteria<Book> getQueryFromGeo(String geo) {
    switch (geo) {
        case 'Europe':
            return Book.where {
                author in getEuropeanAuthors()
            }
        case 'England':
            return Book.where {
                author in getEnglishAuthors() &&
                        publishYear == '1999'
            }
        default:
            return Book.where {}
    }
}

还尝试使用 createCriteria 有条件地构建我的查询,但可读性受到影响并且没有 where 查询

附带的编译时检查