何旭东chucai 2012-12-31
Grails(5)GuideBookChapter6GORM
6.3PersistenceBasics
6.3.1SavingandUpdating
defp=Person.get(1)
p.save()
Thissavewillbenotbepushedtothedatabaseimmediately.Itwillbepushedwhenthenextflushoccurs.
try{
p.save(flush:true)//Flushimmediately.
}catch(org.springframework.dao.DataIntegrityViolationExceptione){
}
Grailsvalidatesadomaininstanceeverytimewhenwesaveit.
try{
p.save(failOnError:true)
}catch{}
6.3.2DeletingObjects
defp=Person.get(1)
p.delete()
Almostthesaveasduringsaving
try{
p.delete(flush:true)
}catch(org.springframework.dao.DataIntegrityViolationExceptione){}
Ifweneedbatchdeletingfunction,weuseexecuteUpdate
Customer.executeUpdate("deleteCustomercwherec.name=ldName",
[oldName:"Carl"])
6.3.3UnderstandingCascadingUpdatesandDeletes
6.3.4EagerandLazyFetching
Defaultarelazyfetching
ConfiguringEagerFetching
classAirport{
Stringname
statichasMany=[flights:Flight]
staticmapping={
flightslazy:false
}
}
UsingBatchFetching
Ifweuseeagerfetchallthetimeforallthedata,itwillresultsomeperformanceandmemoryproblems.
classAirport{
Stringname
statichasMany=[flights:Flight]
staticmapping={
flightsbatchSize:10
}
}
Or
classFlight{
…
staticmapping={
batchSize10
}
}
6.3.5PessimisticandOptimisticLocking
defairport=Airport.lock(10)
6.3.6ModificationChecking
isDirty
Wecanusethismethodtocheckifanyfieldhasbeenmodified.
defairport=Airport.get(10)
assert!airport.isDirty()
airport.properties=params
if(airport.isDirty()){
...
}
Wecanalsocheckifindividualfieldshavebeenmodified.
defairport=Airport.get(10)
assert!airport.isDirty()
airport.properties=params
if(airport.isDirty('name')){
…snip...
}
getDirtyPropertyNames
Wecanusethismethodtoretrievethenamesofmodifiedfields.
defairport=Airport.get(10)
assert!airport.isDirty()
airport.properties=params
defmodifiedFieldNames=airport.getDirtyPropertyNames()
for(fieldNameinmodifiedFieldNames){
…snip...
}
getPersistentValue
Wecanalsousethismethodtoretrievethevalueofamodifiedfield.
defairport=Airport.get(10)
assert!airport.isDirty()
airport.properties=params
defmodifiedFieldNames=airport.getDirtyPropertyNames()
for(fieldNameinmodifiedFieldNames){
defcurrentValue=airport."$fieldName"
deforiginalValue=airport.getPersistentValue(fieldName)
if(currentValue!=originalValue){
…snip...
}
}
6.4QueryingwithGORM
DynamicFinders
WhereQueries
CriteriaQueries
HibernateQueryLanguage(HQL)
ListingInstances
defbooks=Book.list()
defbooks=Book.list(offset:10,max:20)//pagination
defbooks=Book.list(sort:"title",order:"asc")//sort
RetrievalbyDatabaseIdentifier
defbook=Book.get(23)
defbooks=Book.getAll(23,93,81)
6.4.1DynamicFinders
classBook{
Stringtitle
DatereleaseDate
Authorauthor
}
classAuthor{
Stringname
}
defbook=Book.findByTitle("ThePython")
book=Book.findByTitleLike("Python%")
book=Book.findByReleaseDateBetween(firstDate,secondDate)
book=Book.findByReleaseDateGreaterThan(someDate)
book=Book.findByTitleLikeOrReleaseDateLessThan("%Python%",someDate)
MethodExpressions
InList,LessThan,LessThanEquals,GreaterThan,GreaterThanEquals
Like,
Ilike-similartoLike,exceptcaseinsensitive
NotEqual,Between,IsNotNull,IsNull
Booleanlogic(AND/OR)
defbooks=Book.findAllByTitleLikeAndReleaseDateGreaterThan(
“%Java%”,newDate()-30)
QueryingAssociations
PaginationandSorting
6.4.2WhereQueries
BasicQuerying
defquery=Person.where{
firstName=="Carl"
}
Personcarl=query.find()
Personp=Person.find{firstName=="Carl"}
defresults=Person.findAll{
lastName=="Luo"
}
==eq
!=ne
>gt
<lt
>=ge
<=le
ininList
==~like
=~ilike
defquery=Person.where{
(lastName!="Carl"&&firstName!="Book")||(firstName=="Carl"&&age>9)
}
defresults=query.list(sort:"firstName")
QueryComposition
Conjunction,DisjunctionandNegation
…snip…
6.4.3Criteria
6.4.4DetachedCriteria
6.4.5HibernateQueryLanguage(HQL)
defresults=
Book.findAll("fromBookasbwhereb.titlelike'Lordofthe%'")
PositionalandNamedParameters
defresults=
Book.findAll("fromBookasbwhereb.titlelike?",["TheShi%"])
Ornamedparameters
defbooks=Book.findAll("fromBookasbookwherebook.author=:author",
[author:author])
PaginationandSorting
defresults=
Book.findAll("fromBookasbwhere"+
"b.titlelike'Lordofthe%'"+
"orderbyb.titlesac",
[max:10,offset:20])
6.5AdvancedGORMFeatures
6.5.1EventsandAutoTimestamping
EventTypes
ThebeforeInsertevent
Firedbeforeanobjectissavedtothedatabase
classPerson{
privatestaticfinalDateNULL_DATE=newDate(0)
StringfirstName
StringlastName
DatesignupDate=NULL_DATE
defbeforeInsert(){
if(signupDate==NULL_DATE){
signupDate=newDate()
}
}
}
ThebeforeUpdateevent
Firedbeforeanexistingobjectisupdated
classPerson{
defsecurityService
StringfirstName
StringlastName
StringlastUpdateBy
staticconstraints={
lastUpdatedBynullable:true
}
defbeforeUpdate(){
lastUpdateBy=securityService.currentAuthenticatedUsername()
}
}
ThebeforeDeleteevent
Firedbeforeanobjectisdeleted.
classPerson{
Stringname
defbeforeDelete(){
ActivityTrace.withNewSession{
newActivityTrace(eventName:"PersonDeleted",data:name).save()
}
}
}
ThebeforeValidateevent
Firedbeforeanobjectisvalidated.
classPerson{
Stringname
staticconstraints={
namesize:5..45
}
defbeforeValidate(){
name=name?.trim()
}
}
TheonLoad/beforeLoadevent
classPerson{
Stringname
DatedateCreated
DatelastUpdated
defonLoad(){
log.debug"Loading${id}"
}
}
TheafterLoadevent
Firedimmediatelyafteranobjectisloadedfromthedatabase:
classPerson{
Stringname
DatedateCreated
DatelastUpdated
defafterLoad(){
name="I'mloaded"
}
}
CustomEventListeners
6.5.2CustomORMMapping
6.5.2.1TableandColumnNames
6.5.2.2CachingStrategy
Settingupcaching
configuredinthegrails-app/conf/DateSource.groovy
hibernate{
cache.use_second_level_cache=true
cache.use_query_cache=true
cache.provider_class='org.hibernate.cache.EhCacheProvider'
}
6.5.2.3InheritanceStrategies
6.5.2.4CustomDatabaseIdentity
6.5.2.9CustomCascadeBehaviour
…snip...
References:
http://grails.org/doc/latest/guide/GORM.html#persistenceBasics
http://grails.org/doc/latest/guide/index.html