保存和更新
def p = Person.get(1) p.save()不及时保存到数据库
def p = Person.get(1) try { p.save(flush: true) } catch (org.springframework.dao.DataIntegrityViolationException e) { // deal with exception }及时保存到数据库
def p = Person.get(1) try { p.save(failOnError: true) } catch (ValidationException e) { // deal with exception }保存时,验证出现出错,抛出异常
删除对象
def p = Person.get(1) p.delete()
def p = Person.get(1)和save一样try { p.delete(flush: true) } catch (org.springframework.dao.DataIntegrityViolationException e) { flash.message = "Could not delete person ${p.name}" redirect(action: "show", id: p.id) }
deleteAll
方法,如果想进行批量删除可以通过,如下方法
Customer.executeUpdate("delete Customer c where c.name = :oldName", [oldName: "Fred"])
理解级联更新和删除
无论是一对一,一对多还是多对多,如果你定义了 belongsTo ,更新和删除将会从拥有类到被它拥有的类(关联的另一方)级联操作.
如果你 没有 定义 belongsTo 那么就不能级联操作,你将不得不手动保存每个对象.
下面是一个例子: 如果我现在创建一个 Airport 对象,并向它添加一些 Flight 它可以保存这个 Airport 并级联保存每个flight,因此会保存整个对象图: 相反的,如果稍后我删除了这个 Airport 所有跟它关联的 Flight也都将会被删除: 然而,如果我将 belongsTo 去掉的话,上面的级联删除代码就了. 不能工作. 为了更好地理解,take a look at the summaries below that describe the default behaviour of GORM
with regards to specific associations.
设置了belongsTo的双向一对多 如果是双向一对多,在多的一端设置了belongsTo,那么级联策略将设置一的一端为"ALL",多的一端为"NONE".
单向一对多 如果是在多的一端没有设置belongsTo单向一对多关联,那么级联策略设置将为"SAVEUPDATE".
没有设置belongsTo的双向一对多 如果是在多的一端没有设置belongsTo的双向一对多关联,那么级联策略将为一的一端设置为"SAVE-UPDATE" 为多的一端设置为"NONE".
设置了belongsTo的单向一对一 如果是设置了belongsTo的单向一对一关联,那么级联策略将为有关联的一端(A->B)设置为"ALL",定义了belongsTo的一端(B->A)设置为"NONE".
立即加载和延迟加载
class Airport { String name static hasMany = [flights: Flight] }
class Flight { String number Location destination static belongsTo = [airport: Airport] }
class Location { String city String country }grails默认是延迟加载
class Airport { String name static hasMany = [flights: Flight] static mapping = { flights lazy: false } }设置立即加载
class Airport { String name static hasMany = [flights: Flight] static mapping = { flights batchSize: 10 } }
class Flight {
…
static mapping = {
batchSize 10
}
}
设置批量加载,比如:一个机场有30架飞机,如果没有设置批量加载,要取出1个机场3架飞机,要执行31次查询,假使按照上面批量加载配置,则需要4次查询就可以完成。
悲观锁和乐观锁
乐观锁
def airport = Airport.get(10)try { airport.name = "Heathrow" airport.save(flush: true) } catch (org.springframework.dao.OptimisticLockingFailureException e) { // deal with exception }
悲观锁
def airport = Airport.get(10) airport.lock() // lock for update airport.name = "Heathrow" airport.save()
def airport = Airport.findByName("Heathrow", [lock: true])
def airport = Airport.createCriteria().get {
eq('name', 'Heathrow')
lock true
}
修改检查
def airport = Airport.get(10) assert !airport.isDirty()airport.properties = params if (airport.isDirty()) { // do something based on changed state }
def airport = Airport.get(10) assert !airport.isDirty()airport.properties = params if (airport.isDirty('name')) { // do something based on changed name }
def airport = Airport.get(10) assert !airport.isDirty()getPersistentValue获取flush以后修改的数据airport.properties = params def modifiedFieldNames = airport.getDirtyPropertyNames() for (fieldName in modifiedFieldNames) { // do something based on changed value }
def airport = Airport.get(10) assert !airport.isDirty()airport.properties = params def modifiedFieldNames = airport.getDirtyPropertyNames() for (fieldName in modifiedFieldNames) { def currentValue = airport."$fieldName" def originalValue = airport.getPersistentValue(fieldName) if (currentValue != originalValue) { // do something based on changed value } }