1

在收集作者及其书籍的数据库中,我们将书籍添加AuthorBook实例。

但是,Author可能有尚未添加到数据库的书籍。Author这就是为什么我们有一个外部理智计数器,告诉我们一个人实际出版了多少本书。如果numberOfKnownBooks等于Book数据库中的实例数,那么我们认为我们有一个Author完整的参考书目。

数据模型

获取所有Authors参考书目完整的 SQL 查询将在 SQL 中这样编写:

select author.id, count(*)
from book inner join author on book.author_id=author.id
group by author.number_Of_Known_Books, author.id
having count(*) = author.number_Of_Known_Books

这里的困难在于连接指向相反的方向,并且正常示例通常显示如何创建查询以获取Books与 连接Authors,而不是相反。

我在 stackoverflow 中找到了一些文章,解释了如何在普通 JPQL 中执行类似的操作(减去 group by ... 有复杂性)@Query但是在 GORM 6.1+ 中的数据服务中的注释所期望的 DSL 中执行此操作,我得到一个异常,发生在 AST 生成的代码的地牢中,说它executeQueryjava.lang.Object. 这是一个合理的投诉,但我不知道为什么会这样。不幸的是,无法逐步调试此代码。

这是我的数据服务:

import grails.gorm.services.Query
import grails.gorm.services.Service


@Service
abstract class AuthorService {

    @Query("""
            select a.*, count(a.id)
            from ${Book b} join ${b.author} a
            group by a.numberOfKnownBooks, a.id
            having count(*) = a.numberOfKnownBooks
""")
    abstract List<Author> retrieveCompleteAuthors()
}

更新:根据 jeff 的说明删除了无用的注释 @GrailsCompileStatic 和 @Transactional

完整解决方案,使用正确的 JPQL 查询:

@Service(Author)
abstract class AuthorService {
    @Query("""
        select auth from ${Author auth}  where auth.id in (
            select a.id
            from ${Book b} join ${b.author} a
            group by a.numberOfKnownBooks, a.id
            having count(*) = a.numberOfKnownBooks
        ) 
""")
    abstract List<Author> retrieveCompleteAuthors()
}
4

1 回答 1

1

我希望这不是您真正想要的 HQL,但这是一个单独的问题。如果你做这样的事情,你问的错误应该会消失......

import grails.gorm.services.Query
import grails.gorm.services.Service

@Service(Author)
abstract class AuthorService {

    @Query('''
            select a.*, count(a.id)
            from ${Book b} join ${b.author} a
            group by a.numberOfKnownBooks, a.id
            having count(*) = a.numberOfKnownBooks
    ''')
    abstract List<Author> retrieveCompleteAuthors()
}
于 2018-08-27T14:39:31.157 回答