繼續昨天沒分享到的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方法,目前不同情況,兩者都有用著到的時候。