0

假设我在 Grails 2.1.5 项目中有一本现有的域书。到目前为止,我总是从这个表中删除 Books。但现在我不想物理删除书籍,而是存档它们。这样我就不必更改执行 Book.get/findXX/executeQuery/... 甚至 Author.books -> 的代码中的任何内容,以便我只找到未存档的书籍。

所以我认为使用扩展域类可能会很好(因为 Grails > 2.x)。

例如

class ArchivableBook {
    // some properties
    static mappings = {table 'book'}
}

class Book extends ArchivableBook {
    // ...
}

class HistoricalBook extends ArchivableBook {
    // ...
}

(也许让 HistoricalBook 扩展 Book 就足够了)

我知道在数据库级别上,Book 中会有一个“类”列,用于识别它是 Book 还是 HistoricalBook。

所以这是我的问题:现在存档一本书的最佳方式是什么?不知何故,在我看来,我只需要将类列设置为新值......但到目前为止,我还没有弄清楚如何以简单的方式做到这一点。是否可以将 Book 转换为 HistoricalBook 而不是保存它?或者我是否必须删除这本书并创建一个具有相同 ID 的 HistoricalBook?

4

2 回答 2

3

所以我会以不同的方式处理这个问题

将“归档”属性添加到现有类中。

class Book {
    ...
    Boolean archived
    ...
}

然后,只需将其设置为 true,而不是 delete。

然后使用休眠过滤器插件过滤掉归档的书籍。

class Book {
    ...
    Boolean archived
    ...
    static hibernateFilters = {
        notArchivedFilter(condition:'archived=0', default:true)
    }
}

这将适用于所有情况,除非查询不是从标准请求(例如 Quartz 作业)完成或通过.get(). .get()可以改成.findById()

于 2013-09-23T20:23:30.860 回答
0

您所指的“类”列称为鉴别器列,我不相信您可以更改它,至少不容易更改。我想你会发现,沿着这条路走下去会给你带来更多的头痛而不是好处。

但是,您可以在 src/groovy 中创建一个抽象类,并从它继承两个域类。然后,您将得到两个具有公共字段的表(Book 和 HistoricalBook)。在您的Book.delete服务/控制器功能中,您可以创建一个HistoricalBook并删除Book.

** 编辑 **

src/groovy/(包名)/ArchivableBook.groovy

abstract class ArchivableBook {

    String name
    //other properties

    static constraints = {
      ...
    }

}

grails-app/domain/(包名)/Book.groovy

class Book extends ArchivableBook {
    // ...
}

grails-app/domain/(包名)/HistoricalBook.groovy

class HistoricalBook extends ArchivableBook {
    // ...
}
于 2013-09-23T18:13:22.913 回答