如何在Grails中保存或更新?

时间:2011-04-26 07:32:25

标签: grails save

如果记录不存在,则应插入。 如果记录存在,Grails应该进行更新。

new MyEntity(attr1:'val1', attr2:'val2').saveOrUpdate()????

修改 我根据您的建议修改了我的代码:

List<NutDto> res = np.parseNutData(file.inputStream);
for(NutDto cellValue : res){
    def nutInstance = NutData.get(cellValue.getIdd())       
    System.out.println("nutInstance = " + nutInstance);         
    if(nutInstance){
        System.out.println("Exists : " + nutInstance);
        nutInstance.foo=cellValue.getFoo()
        nutInstance.bar=cellValue.getBar()              
    }
    else{
        System.out.println("Not Exists")
        nutInstance =   new NutData(idd:cellValue.getIdd(),
                foo:cellValue.getFoo(),
                bar:cellValue.getBar())
    }

    def saveres = nutInstance.save(failOnError: true);
    println("saveres = " + saveres);
    nutInstance.errors.each { println it }
}

仍然没有更新。抛出错误。

Field error in object 'sps.NutData' on field 'idd': rejected value [123456-1234]; codes [sps.NutData.idd.unique.error.sps.NutData.idd,sps.NutData.idd.unique.error.idd,sps.NutData.idd.unique.error.java.lang.String,sps.NutData.idd.unique.error,nutData.idd.unique.error.sps.NutData.idd,nutData.idd.unique.error.idd,nutData.idd.unique.error.java.lang.String,nutData.idd.unique.error,sps.NutData.idd.unique.sps.NutData.idd,sps.NutData.idd.unique.idd,sps.NutData.idd.unique.java.lang.String,sps.NutData.idd.unique,nutData.idd.unique.sps.NutData.idd,nutData.idd.unique.idd,nutData.idd.unique.java.lang.String,nutData.idd.unique,unique.sps.NutData.idd,unique.idd,unique.java.lang.String,unique]; arguments [idd,class sps.NutData,123456-1234]; default message [Property [{0}] of class [{1}] with value [{2}] must be unique]

值未更新。

编辑2

package sps    
class NutData {

    String idd
    String foo
    String bar


    static constraints = {
        idd(blank:false, unique:true)
    }

    static mapping = {
        table 'M_NUT_DATA'
        version false
        id generator: 'assigned', name: "idd", type: 'string'
        foo column:'FOO_COL'
        bar column:'BAR_COL'        
    }

    String toString(){
        return idd + '_' + foo
    }
}

7 个答案:

答案 0 :(得分:11)

动态查找程序可用于此目的。

使用 findOrSaveBy * ,您的第一个示例代码将如下编写:

def entity = MyEntity.findOrSaveByAttr1AndAttr2( val1, val2 )

文档:http://grails.org/doc/latest/ref/Domain%20Classes/findOrSaveBy.html

答案 1 :(得分:3)

.save()应该全部执行此操作,但这取决于您创建对象的方式。

如果使用new MyEntity(..) grails将创建记录,如果从数据库获取对象,则保存将进行更新。

答案 2 :(得分:2)

您可以使用以下代码(将Widget替换为您的类/实体):

def widgetInstance = Widget.findByName('firstWidget') ?: new Widget(name: 'firstWidget').save(failOnError: true)

保存函数“failOnError:true”的参数将确保代码在出现错误时失败。

答案 3 :(得分:1)

就像elCapitano所说,这里的问题在很大程度上取决于你获得对象的方式。

如果你从数据库中获取对象,然后修改它,你只需要在对象上调用save()。

如果您创建一个新对象(如您的示例):现在它取决于您如何知道“数据库中已存在相同的对象”。您必须执行查询以确定对象是否已存在,然后执行更新或相应地创建。这没有捷径。

但更常见的是,问题并不复杂,因为通常只有在已经加载对象(例如表单)才能更新对象以供用户编辑。否则,您知道需要创建对象。

您可以使用grails scaffolding函数查看Grails执行CRUD(create-update-delete)的典型模型。

答案 4 :(得分:0)

为了更新记录,我们应该清楚 - 如果我的域类有a,b,c和d字段。然后,在尝试保存时,如果a和b相同而不是更新记录,则另外明智地插入新记录。

因此,首先要确定域类中的这些字段。

然后我们需要在域类上使用saveOrUpdate方法,它执行以下操作:

//This method is present in domain class
saveOrUpdate()
{
   //listOfFields is a list of fields that are identifiers or the once that decide whether to update or insert.
   def existingObject = DomainClass.findWhere([this.properties.subMap(listOfFields)])

   if(existingObject)
   {
      // Hey!!! This object already exists in DB. Let us update it .... 
      // Update the existingObject and save the same
   }
else{
    // No object already exists in the DB so, let us create a new one and save it.
   } 
}

如果您想要完成同样的工作实施,请参阅我的博客:

http://www.intelligrape.com/blog/2011/03/15/implementing-saveorupdate-for-domain-classes/

希望这有帮助。

答案 5 :(得分:0)

  
    

a'.save()'应该全部执行此操作,但这取决于您创建对象的方式。

         

如果您使用'new MyEntitiy(..)'grails将创建记录,如果您从&gt;&gt;获得对象数据库,保存将进行更新。

  

恰到好处。首先检索对象,检查更改的内容然后将其保存回来。 使用new会在保存期间在数据库中创建另一个条目“只是因为它是对象。

def gottenFromDB = TheObject.get( params.id ) ; //for example
def updatesObject = new MakeNewObjectFromJSON( request ) ; // this one contains the updates

// either check property  by property or just update all properties 
// whatever is more efficiente or if you don't care.

gottenFromDB.prop1 = updatesObject.prop1
gottenFromDB.prop2 = updatesObject.prop2
gottenFromDB.propN   = updatesObject.propN

gottenFromDB.save() ; // this will perform "update"

答案 6 :(得分:0)

findOrSaveBy... 更新现有数据。 因此,我为名为Person的域编写了自己的代码。

Boolean saveOrUpdate(Integer id, String name, Status status, Date startDate) {

    Person person = Person.findById(id)

    //If the person is new, create a new instance and assign ID
    if(!person) {
        person = new Person()
        person.setId(id.toLong()) 
       /** I set the ID here because I am using Postgres and I want to assign the ID manually
       `static mapping = {
           id generator: 'assigned'
        }`
       */
    }

    person.name = name
    person.status = status
    person.startDate = startDate
    person.save(flush: true, failOnError: true)

    if (person?.hasErrors()) {
        log.error("Person ${id} is not saved. Domain Errors: ${person?.errors}")
    }
}