我有一个包含多个域类的Grails项目,我想通过在其中只有一个save()来使持久性服务尽可能可重用。为了尝试实现这一点,我在我的项目中完成了以下工作。
// PersistenceService.groovy
@Transactional
class PersistenceService {
def create(Object object) {
object.save flush: true
object
}
// BaseRestfulController
class BaseRestfulController extends RestfulController {
def persistenceService
def save(Object object) {
persistenceService.create(object)
}
// BookController的
class BookController extends BaseRestfulController {
private static final log = LogFactory.getLog(this)
static responseFormats = ['json', 'xml']
BookController() {
super(Book)
}
@Transactional
def save(Book book) {
log.debug("creating book")
super.save(book)
}
所以基本上我有一堆域例如Author等,每个域都有自己的控制器,类似于bookController。那么有没有办法重用服务来实现持久性,就像我在上面尝试一样?
谢谢
答案 0 :(得分:3)
我正在做类似的事情,但主要是因为我的所有实体实际上并未从数据库中删除,而是“标记”为已删除。对于多个应用程序,您需要这样的方法,因为它对于防止任何类型的数据丢失至关重要。
由于大多数数据库不支持此方案,因此在删除父项时,不能依赖外键删除依赖域实例。 所以我有一个名为GenericDomainService的基本服务类,它具有保存,删除(标记),取消删除(取消标记)的方法。
此服务提供可应用于任何域的基本实现。
class GenericDomainService {
def save( instance ) {
if( !instance || instance.hasErrors() || !instance.save( flush: true ) ) {
instance.errors.allErrors.each {
if( it instanceof org.springframework.validation.FieldError ) {
log.error "${it.objectName}.${it.field}: ${it.code} (${it.rejectedValue})"
}
else {
log.error it
}
}
return null
}
else {
return instance
}
}
def delete( instance, date = new Date() ) {
instance.dateDisabled = date
instance.save( validate: false, flush: true )
return null
}
def undelete( instance ) {
instance.dateDisabled = null
instance.save( validate: false, flush: true )
return null
}
}
然后,在我的控制器模板中,我总是声明两个服务:泛型和具体(可能不存在):
def ${domainClass.propertyName}Service
def genericDomainService
哪个会将名为Book的域转换为:
def bookService
def genericDomainService
在控制器方法中,我使用如下服务:
def service = bookService ?: genericDomainService
service.save( instance )
最后,给定域的服务将继承此服务,为这些操作提供(如果需要)自定义逻辑:
class BookService extends GenericDomainService {
def delete( instance, date = new Date() ) {
BookReview.executeUpdate( "update BookReview b set b.dateDisabled = :date where b.book.id = :bookId and b.dateDisabled is null", [ date: date, bookId: instance.id ] )
super.delete( instance, date )
}
def undelete( instance ) {
BookReview.executeUpdate( "update BookReview b set b.dateDisabled = null where b.dateDisabled = :date and b.book.id = :bookId", [ date: instance.dateDisabled, bookId: instance.id ] )
super.undelete( instance )
}
}
希望有所帮助。