grails note -GORM

来源:互联网 发布:餐牌平面设计软件 编辑:程序博客网 时间:2024/05/07 03:44

grails create-app helloworld
grails> create-controller hello

grails> run-app

grails test-app # unit test

grails war # generate a war file to deploy

部署Grails的时候,你要确保你容器的JVM总是使用 -server 选项,并且还有有足够的内存。推荐的VM参数如下:
-server -Xmx512M -XX:MaxPermSize=256m


GORM

grails create-domain-class book # to create a domain file : grails-app/domain/Book.groovy

grails console# loads an interactive GUI where you can run Groovy commands with access to GROM and so on

基本的增删改查

   create:

  def p = new Person(name: "Fred", age: 40, lastVisit: new Date())
  p.save()

   query:

def p1 = Person.get(1)

def p2 = Person.read(1)  // read-only model ,the change of p2 will not effect the database

def p3 = Person.load(1) // lazy-load, no database access until a method other than getId() is called
assert 1 == p.id

   update:

def p = Person.get(1)
p.name = "Bob"
p.save()

   delete:

def p = Person.get(1)
p.delete()

在console里操作数据库默认会延迟提交,要立即提交时使用flush参数,如 book.save(flush:true)

Relationships

1. Unless specified explicitly at both ends, a relationship exists only in the direction it is defined.

2. Many-to-one unidirectional

class Face {
Nose nose
}
class Nose {
}

3. Many-to-one bidirectional

class Face {Nose nose}class Nose{static  belongsTo = [face:Face]}


'Nose' belongs to 'Face' means saves and deletes will cascade from Face to the associated Nose.

new Face(nose:new Nose()).save() // will create a Face and its Nose

the inverse is not true and will result in an error due to a transient Face

new Nose(face:new Face()).save() // will cause an error

4. one-to-one bidirectional


hasOne only works with bidirectional relationships, using this property puts the foreign key on the inverse table

table Nose will have a column 'face_id' to hold the relationship


5. One-to-many unidirectional


because of 'hasMany', this will create 3 tables :

author(name), book(title), author_book(author_book_id, book_id)

'hasMany' will create a join table

hasMany : a java.uti.Set type property 'books' will be injected into 'Author',  eg : author_1.books

Set books will be lazily initialized on first access. This can lead to the n+1 problem

The default cascading behaviour is to cascade saves and updates, but not deletes unless abelongsTois also specified in the 'Many' side 'Book'

6. many-to-many bidirectional

package helloworld/*one-to-many with Orders */class Customer {String namestatic hasMany = [orders : Orders]    static constraints = {    }    static mapping = {    orders fetch : 'join'    }}
package helloworld/*many-to-many with Author */class Book {static belongsTo = Authorstatic hasMany = [authors:Author]    String title}



Grails supports many-to-many relationships by defining a hasMany on both sides of the relationship and having abelongsToon the owned side of the relationship:


Book: owned side, Author:  owing side, 

The owning side of the relationship, in this case Author, takes responsibility for persisting the relationship and is the only side that can cascade saves across. so 

author.addToBooks(book) is ok and the book.addToAuthors(author) not

a join table author_books(author_id, book_id) will be created

使用心得:



默认情况下,查询Author时的过程:查询一条语句获得N个author,然后为每个author ,再查N条语句, 假设第i 个author所关联的book数为Mi, 侧第i个author又会执行Mi个SQL, 所以总共会执行的SQL语句的个数为:1 + N + (M1 + M2 + ... + Mn),   是N+1 问题的升级版


加上fetch :'join'后


查询author表时会使用 left outer join 关联author_books中间表同时获得author 和book_id, 而对每个Book 还是会根据每个book_id执行再去执行Mi次SQL语句

SQL总数为: 1 + (M1 + M2 +...+ Mn)


去掉 fetch : ’join' 后, 手动写SQL :


执行SQL 一条: 


返回的结果是一个列表, 每个元素都是一个(author, book)组成的元组



 Basic Collection types



Composition in GORM


define both Person and Address in Person.groovy, then no table 'address' in DB. 

'embedded'  will add columns of table Address into table Person

Inheritance in GROM


by default, Content and BlogEntry share the same table content(author, url, class), the column 'class' indicate this row is Content or BlogEntry

Polymorphic Queries

def content = Content.list()def blogEntry = BlogEntry.list()

Sets, Lists and Map

by default, a java.util.Set property will be used. 

class A{  static hasMany = [bees:B]}class B{}
use java.util.SortedSet :  the many side has to implement Comparable, so the a.bees will be sorted.

class A{
  SortedSet bees  static hasMany = [bees:B]}class B implements Comparable{  int compareTo(obj){    this.compareTo(ojb)  }}

Eager and Lazy Fetching

















0 0
原创粉丝点击