Grails中数据的保存、更新和删除。

来源:互联网 发布:一橙科技网络投诉电话 编辑:程序博客网 时间:2024/05/22 17:45

持久化基础

关于Grails要记住一个关键点,就是在底层Grails使用 Hibernate 进行持久化。假如你是使用 ActiveRecord 或者 iBatis/MyBatis背景,Hibernate's"session"模式可能会感到一点奇怪。

Grails为当前正在执行的请求自动绑定一个Hibernate session。这让你可以使用save an delete 方法,以及透明使用 GORM其他方法。

后写事务

Hibernate的一个有用功能通过直接调用 JDBC甚至其他的框架来帮你执行save 或者 delete操作,在这一点上它不一定执行任何SQL操作。Hibernate SQL 语句分批并尽可能晚地执行。通常在清空或关闭session时才结束请求。这是Grils帮你管理Hibernate session自动为你做的。

Hibernate 尽可能缓存数据库更新,当它知道需要一个刷新或者以编程方式触发刷新时,只刷新实际改变的内容。通常Hibernate执行缓存刷新是在执行查询的时候,因为缓存的信息可能包含在查询结果中。但是,只要你执行保存、更新、删除不冲突,他们会被分批执行直到session被刷新。这可能是为大量数据写入数据库所做的尽可能大的性能提升工作。

注意,刷新和提交事务是不一样的。如果你的actions是一个事务,刷新将执行SQL更新,但数据库在事务序列存储的改变,只到事务提交,确认事务结束时才更新。

保存和更新

一个使用 save 方法的例子看起来像这样:

def p = Person.get(1)

p.save()

这个保存并没有被立即推进数据库-当下一个刷新发生时才被推进数据库。但有的时候你想控制某些语句的执行,用Hibernate语言来说,当 session被刷新时,你可以在执行save方法时使用flush参数:

def p = Person.get(1)

p.save(flush: true)

请注意,在这种情况下,以往所有缓存等待的SQL语句包括保存和删除等等,将于数据库同步。这要让你捕获任何异常,在高并发的情况下使用乐观锁:

def p = Person.get(1)

try {

    p.save(flush: true)

}

catch (org.springframework.dao.DataIntegrityViolationException e) {

    // deal with exception

}

要记住的另一件事是,每一次Grails验证一个域的实例你都要保存。假如验证失败,域实例不会被持久化到数据库。默认情况下, save()在这里简单返回一个 null ,但是你要让她抛出一个异常,可以使用 failOnError 参数:

def p = Person.get(1)

try {

    p.save(failOnError:true)

}

catch (ValidationException e) {

    // deal with exception

}

你甚至可以更改 Config.groovy配置文件中的默认配置。要记住,当你保存已经与用户数据绑定的域实体时,发生验证异常的可能性是很高的,你可能不想将这些异常传播给最终用户。

删除对象

一个 delete 方法的例子看起来像这样:

def p = Person.get(1)

p.delete()

就像保存一样,Hibernate会使用后写事务的方法去定义删除;定义立即删除你可以使用 flush 参数:

def p = Person.get(1)

p.delete(flush: true)

使用flush参数在发生一个删除是让你可以捕捉到任何错误。一个可能发生的常见错误是你违反了数据库约束,虽然这通常是编程和模式的错误。下面的例子展示如何捕捉一个DataIntegrityViolationException 异常,这是你违反数据库约束时抛出的:

def p = Person.get(1)

try {

   p.delete(flush: true)

}

catch (org.springframework.dao.DataIntegrityViolationException e) {

    flash.message = "Could notdelete person ${p.name}"

    redirect(action: "show", id: p.id)

}

注意,Grails 没有提供 deleteAll方法来删除所有数据。通常可以通过布尔值来批量删除数据。

如果你真的需要批量删除数据,你可以使用executeUpdate法来执行批量的DML语句:

Customer.executeUpdate("delete Customer c where c.name = :oldName",

                       [oldName:"Fred"])

 

原创粉丝点击