close

先前我提過,Grails 底層其實是 Spring framework + Hibernate。
我相信很多人都用過 Hibernate,他為我們在開發應用系統時,省下不少時間。
同樣的功能,在 Grails 有個專有名詞,叫做 GORM (Grails Object Relational Mapping)。Grails 把 Hibernate 及相關的 annotations 無縫接軌到 Grails中。

我會花數篇文章介紹 Grails 的 GORM 功能與約定作法。因為在我的學習過程中,這部分我遇到不少問題。雖然已解決了大部分,但仍就有一點點的部分還在奮鬥中。
因此我相信各位也一定會經過這個過程。但是對於 Hibernate 的觀念,我比較不會在我的文章裡提到。因為 GORM 基本上就是把 Hibernate  拿過來用,只是改成 Groovy 的語法。所以相關的 Hibernate 觀念,建議你還是回去讀一下 Hibernate 相關的文章會比較好。

在 Grails 的約定目錄中,有個目錄叫做 Domain classes。凡是只要是在這個目錄中的物件,Grails 就會把他當作是要跟資料庫做 GORM用的。一般而言,你不太需要再去多設定其他的 annotations。由於我是用 Grails 2.5.1 來做介紹,所以我這邊是以官網為主,然後以我的範例為輔,並講解我在自學過程中所遇到的一些沒沒角角,以及如何解決。

官網如下:https://grails.github.io/grails-doc/2.5.1/guide/GORM.html

首先我們先建立一個資料表,叫做  book。這在 IntelliJ 中的操作如下:

lesson3-new_domain_class.png 


lesson3-enter_domain_class_name.png 
在上述畫面中,輸入 book,你要輸入「Book」也可以,之後Grails都會轉換成 Book。
按下 OK,注意 IntelliJ 中下方的 console 畫面的 log


lesson3_domain_class_done.png 
Grails 會產生兩個檔案,一個是在 Domain classes 的目錄中產生 book.groovy,另一個是 BookSpec.groovy

lesson4-domain_class_spec.png 

book.groovy 就是 GORM 的 mapping檔,這個檔將來會在資料庫中自動產生book 資料表。
而 BookSpec.groovy 則是將來要用來做自動測試時所要用到的 unit test 程式檔。這在之後會在講到。本篇重點先放在 Domain class 的基本設定
我們先看一下 book.

package hello
class Book {
    static constraints = {
    }
}

Grails 的 GORM 物件,約定好會有個隱含的主鍵,叫做 id,他的類型是 bigint (或說是 long)。所以,在資料庫產生實際的資料表 book時。該資料表中,會有一個欄位叫做 id,資料類型是 bigint。因此,實際的程式應該是:

package hello
class Book {
    long id
    static constraints = {
    }
}

這是在 Grails 所建議的主鍵設定建議。這在後續Grails 在處理關聯、JOIN等過程中會簡單很多。此外,Grails 內建的 Scaffolding (你可以把他想像成資料表記錄維護的功能)預設也僅使用 id 欄位當作主鍵。但實際上,我們有很多時候,或基於一些原因,我們不會想要這樣設定主鍵。例如,書本都有 ISBN。所以你可能會想要將 ISBN設定為主鍵。因此,你可以改成下面

package hello
class Book {
    String isbn;
    static mapping = {
        id      name:'isbn', generator: 'assigned'   //設定主鍵是 isbn,他的值是由程式指定
        isbn    comment:'國際書碼', length: 40        //isbn在資料庫中欄位的註解是'國際書碼',他是 varchar(40)
    }
    static constraints = {
        //我們設定 isbn是 unique,不可 null,也不可是空字串 ascii #0
        //但對於這物件的 isbn是無須這些設定,因為握們在上面已經指定他是主鍵了,所以就已經表示有這些隱含的限制條件了
        isbn    unique: true, nullable: false, blank: false
    }
}

這樣,在資料庫產生 book資料表之後,就只會有 isbn欄位,且該欄位會被設定為主鍵。更多 id 相關的設定請參閱:https://grails.github.io/grails-doc/2.5.1/ref/Data... 。 
我們可以繼續增加其他的欄位。現在我們再增加其他欄位作稍後的測試:

package hello
class Book {
    String isbn;
    String title; 
    int publishedYear
    String authorLastName
    String authorFirstName
    String language
    static mapping = {
        id               name:'isbn', generator: 'assigned'   //設定主鍵是 isbn,他的值是由程式指定
        isbn             comment:'國際書碼', length: 40        //isbn在資料庫中欄位的註解是'國際書碼',他是 varchar(40)
        title            comment:'書名', length:60
        publishedYear    comment:'出版年份'
        authorLastName   comment:'作者姓氏', length:30
        authorFirstName  comment:'作者名', length:30
        language         comment:'表示這書是用什麼語言寫的', length:20
    }
    static constraints = {
        //我們設定 isbn是 unique,不可 null,也不可是空字串 ascii #0
        //但對於這物件的 isbn是無須這些設定,因為握們在上面已經指定他是主鍵了,所以就已經表示有這些隱含的限制條件了
        isbn             unique: true, nullable: false, blank: false
        title            blank:false
        publishedYear    nullable:false
        authorLastName   nullable:false
        authorFirstName  nullable:false
    }
}

下一篇文章,我將介紹複合主鍵與關連,你將會發現在 Grails 中,對於 ORM 的約定作法,比 Java 中使用 xml 或是 annotations 的作法更簡單。

arrow
arrow
    創作者介紹
    創作者 grails 的頭像
    grails

    Groovy / Grails 介紹

    grails 發表在 痞客邦 留言(0) 人氣()