Grails-命令对象、服务方法

Grails-命令对象、服务方法,grails,service,controller,command-objects,Grails,Service,Controller,Command Objects,我不是一个精通编程的人,所以请容忍我 我读过关于command object的博客和文档。我从来没有用过它,我想知道我是否应该用。(我可能应该……) 当用户上传文件时,我的项目需要解析、排序、计算并将结果保存到数据库中 所以根据我读到的其中一个 1) 服务应接收文件上传,解析上传的文件(主要是文档和PDF),使用正则表达式对解析的数据进行排序,并计算数据 2) 命令对象应调用服务,收集结果并将结果发送回控制器,并将结果保存到数据库中 3) 控制器应接收来自视图的请求,从命令对象获取结果,并将结果

我不是一个精通编程的人,所以请容忍我

我读过关于command object的博客和文档。我从来没有用过它,我想知道我是否应该用。(我可能应该……)

当用户上传文件时,我的项目需要解析、排序、计算并将结果保存到数据库中

所以根据我读到的其中一个

1)
服务
应接收文件上传,解析上传的文件(主要是文档和PDF),使用正则表达式对解析的数据进行排序,并计算数据

2)
命令对象
应调用
服务
,收集结果并将结果发送回控制器,并将结果保存到数据库中

3)
控制器
应接收来自
视图
的请求,从
命令对象
获取结果,并将结果发送回
视图

我理解对了吗


谢谢。

是的,您正确理解了它,除了一件事:command对象不应该将数据保存到DB-let服务来执行此操作。命令对象的另一个优点是数据绑定和来自客户端的数据验证。请在此处阅读有关命令对象的详细信息 您还可以在本文中找到关于您的问题的有用信息

是的,您正确理解了它,除了一件事:command对象不应该将数据保存到DB-let服务来执行此操作。命令对象的另一个优点是数据绑定和来自客户端的数据验证。请在此处阅读有关命令对象的详细信息 您还可以在本文中找到关于您的问题的有用信息
我发现这是最好的设置。以下是我在生产中使用的一个示例:

命令对象(携带数据并确保其有效性):

控制器(将请求定向到服务,然后从服务获取响应,并将此响应定向到视图):

服务(处理业务逻辑并从域获取数据):

域(所有数据库查询都在此处处理):


我发现这是最好的设置。以下是我在生产中使用的一个示例:

命令对象(携带数据并确保其有效性):

控制器(将请求定向到服务,然后从服务获取响应,并将此响应定向到视图):

服务(处理业务逻辑并从域获取数据):

域(所有数据库查询都在此处处理):


我想不是。它实际上与是否在服务中执行保存无关—它应该始终尝试在服务中执行复杂的操作,特别是db操作。因此,这是无关紧要的。我倾向于不使用command对象,但已经对位于src/main/groovy中的helper类aka bean产生了兴趣,这些类负责所有的验证和格式化工作。我刚做了一个表格,里面有反馈和理由

起初我以为我会逃脱惩罚

def someAction(字符串反馈、字符串原因){ 一些服务。一些事情(反馈、理由) }

但后来我看起来关闭了,我的表单首先是一个文本区域,然后选择对象是字节,因此上面的内容不起作用,为了简单地修复它而不增加控制器/服务的复杂性,我做了以下操作:

packe some.package
import grails.validation.Validateable

class SomeBean implements Validateable {

    User user

    byte reason
    String feedback

    static constraints = {
        user(nullable: true)
        reason(nullable:true, inList:UsersRemoved.REASONS)
        feedback(nullable:true)
    }

    void setReason(String t) {
        reason=t as byte
    }

    void setFeedback(String t) {
        feedback=t?.trim()
    }
}
现在我的控制器

class SomeController {
  def userService
  def someService
 def doSomething(SomeBean bean){
        bean.user = userService.currentUser
        if (!bean.validate()) {
 flash.message=bean.errors.allErrors.collect{g.message([error : it])}
            render view: '/someTemplate', model: [instance: bean,template:'/some/template']
            return
        }

        someService.doSomeThing(bean)
}
}
现在为我效劳

Class SomeService {
def doSomeThing(SomeBean bean) {

if (bean.user=='A') { 
.....
}


}
所有这些验证都必须在某个地方完成,您可以说没有验证,但在一个好的模型中,您应该进行验证,并将内容存储在适当的结构中,以减少数据库随着时间的推移而过载。很难解释,但简而言之,我谈论的是您的域类对象,并确保您没有设置String某物String某物,甚至没有定义它们的长度等。请严格执行并验证

如果您有一个文本区域,它将存储在后端-因此您需要像上面那样对其进行修剪-您需要确保输入不超过实际db结构的最大字符数,如果未定义,可能为255

通过这样做

  static constraints = {
            user(nullable: true)
            reason(min:1, max:255, nullable:true, inList:UsersRemoved.REASONS)
已经通过控制器中的bean.validate()使其无效,如果用户以某种方式超过了我的前端检查并输入了255个以上

这件事需要时间耐心点

编辑以最终添加该示例字节-需要小心-

当添加任何字符串或任何我已经开始像这样定义特定值的时候,在字节的情况下,如果它是布尔值true false-如果不是则很好,然后将它定义为tinyint

static mapping = {
 //since there is more than 1 type in this case
 reason(sqlType:'tinyint(1)')
 feedback(sqlType:'varchar(1000)')
// name(sqlType:'varchar(70)')
}

如果您查看在db中创建的表,您应该会发现它们是按照定义创建的,而不是标准的255 varchar,我认为这是声明字符串的默认值。

我想不是。它实际上与是否在服务中执行保存无关—它应该始终尝试在服务中执行复杂的操作,特别是db操作。因此,这是无关紧要的。我倾向于不使用command对象,但已经对位于src/main/groovy中的helper类aka bean产生了兴趣,这些类负责所有的验证和格式化工作。我刚做了一个表格,里面有反馈和理由

起初我以为我会逃脱惩罚

def someAction(字符串反馈、字符串原因){ 一些服务。一些事情(反馈、理由) }

但后来我看起来关闭了,我的表单首先是一个文本区域,然后选择对象是字节,因此上面的内容不起作用,为了简单地修复它而不增加控制器/服务的复杂性,我做了以下操作:

packe some.package
import grails.validation.Validateable

class SomeBean implements Validateable {

    User user

    byte reason
    String feedback

    static constraints = {
        user(nullable: true)
        reason(nullable:true, inList:UsersRemoved.REASONS)
        feedback(nullable:true)
    }

    void setReason(String t) {
        reason=t as byte
    }

    void setFeedback(String t) {
        feedback=t?.trim()
    }
}
现在我的控制器

class SomeController {
  def userService
  def someService
 def doSomething(SomeBean bean){
        bean.user = userService.currentUser
        if (!bean.validate()) {
 flash.message=bean.errors.allErrors.collect{g.message([error : it])}
            render view: '/someTemplate', model: [instance: bean,template:'/some/template']
            return
        }

        someService.doSomeThing(bean)
}
}
现在为我效劳

Class SomeService {
def doSomeThing(SomeBean bean) {

if (bean.user=='A') { 
.....
}


}
所有这些验证都必须在某个地方完成,您可以说没有验证,但在一个好的模型中,您应该进行验证,并将内容存储在适当的结构中,以减少数据库随着时间的推移而过载。很难解释,但简而言之,我谈论的是您的域类对象,并确保您没有设置String某物String某物,甚至没有定义它们的长度等。请严格执行并验证

如果您有一个文本区域th
static mapping = {
 //since there is more than 1 type in this case
 reason(sqlType:'tinyint(1)')
 feedback(sqlType:'varchar(1000)')
// name(sqlType:'varchar(70)')
}