iT邦幫忙

DAY 12
3

邊看邊學Groovy/Grails/Gradle系列 第 9

Groovy基本語法(4)-Groovy JDBC語法(4)-使用DataSet語法

繼續昨天沒分享到的DataSet語法(add, findAll),DataSet與之前的execute方法差別只在接觸Native SQL語法的程度,DataSet幾乎不須接觸SQL語法,只要懂得API即可,findAll是query的一種,條件式與SQL語法不同是用Groovy的Abstract Syntax Tree(AST),關於AST尚未提及,有一篇會是跟大家分享AST部分,不過在DataSet這邊並未需要了解AST原理,AST日後再行分享,另外要補充漏掉withBatch這個方法可以使用addBatch批次新增資料
使用DataSet新增資料以及使用withBatch批新增資料範例如下:

import groovy.sql.Sql 

def db=Sql.newInstance("jdbc:mysql://localhost/goo", 
                                            "root",    
                                            "lga2011", 
                                            "com.mysql.jdbc.Driver") 
                                            
def itemInsert='''INSERT INTO openitem (sourceNo, designDoc, receviedDate, closeDate)
                                                     VALUES (?,?,?,?);'''
 
//withbatch方法搭配closure批次新增records
db.withBatch(itemInsert) {src->
    src.addBatch('FPR-11-1234', 'FDDR LT1-08414', '2011-10-18', '2011-12-01')
    src.addBatch('FPR-08-0937', 'FDDR LT0-00568', '2008-09-13', '2008-11-02')
    src.addBatch('FPR-12-0659', 'FDDR LT0-00956', '2012-05-30', '2012-07-09')
}

//使用DataSet,sql instance有dataSet方法,以字串的方式傳入table名稱
batchSet=db.dataSet("openitem")
//add方法新增資料
batchSet.add(sourceNo:'FPR-13-0159', 
                       designDoc:'FDDR LT1-14890',
                       receviedDate:'2013-06-09',
                       closeDate:'2013-10-07')

batchSet.each {
    println "${it.sourceNO}'s ${it.designDoc}"
}    

輸出結果:

接下來介紹DataSet findAll方法,其實就是query的一種,語法簡潔也很值觀,方法後面接的是closure,closure裡面是條件,但條件間的and/or不是SQL而是Groovy的Abstract Syntax Tree(AST),故Groovy透過parser幫我們closure裡的條件式轉換成SQL語法,當我們得到findAll傳回的DataSet物件後可以下xxx.sql即可回傳一String(SQL的陳述式),因此換句話說,如果findAll closure裡的條件若Grvooy編譯器產生錯誤,則Groovy不會連線資料庫傳送錯誤的SQL敘述,而在產生SQLException,Anyway,範例如下:

import groovy.sql.Sql 

def db=Sql.newInstance("jdbc:mysql://localhost/goo", 
                                            "root",    
                                            "lga2011", 
                                            "com.mysql.jdbc.Driver") 
                                            

//使用DataSet,sql instance有dataSet方法,以字串的方式傳入table名稱
batchSet=db.dataSet("batchtable")

//使用findAll, 傳回的dataset物件
afterFour=batchSet.findAll { //findAll closure中放的是條件式
    it.batchno > 'B-012' && it.batchno < 'B-016'
    // ||代表 or ,==代表等於 (Groovy的AST)
}
println afterFour.sql //findAll其實是幫我們parser
                      //條件式成SQL語法
println afterFour.parameters //條件的參數,以list表示

println '\n'
afterFour.each{
    print "${it.source}'s".padRight(22) 
    print "corresonding Batch is ${it.batchno}"
    print '\n'
}

輸出結果:

select * from batchtable where (batchno > ? and batchno < ?)
[B-012, B-016]


FPR-12-0501's         corresonding Batch is B-013
FPR-12-0502's         corresonding Batch is B-013
NCD-CS-004's          corresonding Batch is B-013
FPR-12-0492's         corresonding Batch is B-013
FPR-12-0120-RB's      corresonding Batch is B-013
FPR-11-0695-RC's      corresonding Batch is B-013
FPR-12-0451's         corresonding Batch is B-013
CIR-2012-OP5-012-RA's corresonding Batch is B-013
FPR-12-0120-RB's      corresonding Batch is B-013
FPR-11-0664-RB's      corresonding Batch is B-014
FPR-11-0549-RB's      corresonding Batch is B-014
FPR-12-0356-RA's      corresonding Batch is B-014
FPR-12-0493's         corresonding Batch is B-014
CIR-2012-OP1-021's    corresonding Batch is B-014
CIR-2012-OP4-020's    corresonding Batch is B-014
FPR-12-0524's         corresonding Batch is B-015
UFCR-NP4-20779's      corresonding Batch is B-015
FPR-12-0511-RA's      corresonding Batch is B-015
FPR-12-0460's         corresonding Batch is B-015
CIR-2012-OP4-018's    corresonding Batch is B-015
FPR-12-0524's         corresonding Batch is B-015
FPR-12-0460's         corresonding Batch is B-015

DataSet有其好處也有其限制,好處是簡單的條件式可以接觸比較少的SQL語法,但面對比較複雜的SQL語法個人感覺還是回歸db.execute方法,目前不同情況,兩者都有用著到的時候。


上一篇
Groovy基本語法(4)-Groovy JDBC語法(3)-update/delete及query/rows語法
下一篇
Groovy重要觀念(1)-MOP中GroovyInterceptable/TracingInterceptor
系列文
邊看邊學Groovy/Grails/Gradle27

尚未有邦友留言

立即登入留言