便捷輕巧的Groovy數據庫操作
1.數據庫連接配置
<span style="font-family:'宋體', SimSun;font-size:16px;">//數據庫連接配置<br>def db = [<br> url:'jdbc:h2:mem:groovy',<br> user:'root',<br> password:'root',<br> driver:'org.h2.Driver'<br>];<br></span>
2.創建數據庫連接,這里使用到Groovy的Sql類。
<span style="font-family:'宋體', SimSun;font-size:16px;">//創建數據庫連接<br>def sql = Sql.newInstance(db.url, db.user, db.password, db.driver);<br></span>
3.創建數據庫表
<span style="font-size:14px;font-family:'宋體', SimSun;">//創建數據庫表<br>sql.execute('''<br> CREATE TABLE account(<br> id integer NOT NULL,<br> name varchar(20),<br> url varchar(100)<br> )<br>''');<br> </span>
使用了groovy.sql.Sql類的execute方法執行一條SQL命令,在數據庫groovy中創建了表account。
4.向數據庫表中寫入數據,并查詢寫入的數據
<span style="font-family:'宋體', SimSun;font-size:16px;">//寫入數據<br>def datas=[<br> [100, 'Jack', 'http://www.jack.net'], <br> [101, 'Groovy', 'http://groovy.com'], <br> [102, 'Apache', 'http://apache.org']<br>];<br>datas.each { param-><br> sql.execute('INSERT INTO account(id, name, url) values(?,?,?)', param);<br>}<br>println('Insert After:');<br>sql.eachRow('SELECT id, name, url FROM account') { row-><br> printf('|%d|%s|%s|\n', row.id, row.name, row.url);<br>}<br></span>
從4中的程序可以看出,向表account中寫入3條數據記錄,然后查詢并遍歷出查詢結果,再這一過程中使用了Groovy的閉包特性,列表數據結構。
下面是查詢的結果:
<span style="font-family:'宋體', SimSun;font-size:16px;">Insert After:<br>|100|Jack|http://www.jack.net|<br>|101|Groovy|http://groovy.com|<br>|102|Apache|http://apache.org|<br></span>
5.查詢數據
<span style="font-family:'宋體', SimSun;font-size:16px;">//查詢第一行數據<br>def rs=sql.firstRow('SELECT * FROM account');<br>println('Query First Row:');<br>println(rs);<br></span>
Groovy的Sql類提供了大量的查詢方法(具體參見Groovy的API),上面5中的代碼是查詢第一條記錄,返回的類型是GroovyRowReasult,其實現了Map接口。打印輸出則是一個Groovy的Map類型表示。如下:
<span style="font-family:'宋體', SimSun;font-size:16px;">Query First Row:<br>[ID:100, NAME:ZhangSan, URL:http://aiilive.blog.51cto.com]<br></span>
6.更新數據
<span style="font-family:'宋體', SimSun;font-size:16px;">def name='ZhangSan';<br>def url='http://aiilive.blog.51cto.com';<br>sql.executeUpdate("UPDATE account SET name=$name, url=$url where id=100");<br>println('Update After:');<br>sql.eachRow('SELECT id, name, url FROM account') { row-><br> printf('|%d|%s|%s|\n', row.id, row.name, row.url);<br>}<br></span>
7.刪除數據
<span style="font-family:'宋體', SimSun;font-size:16px;">//刪除指定條件的數據<br>name='Groovy';<br>sql.executeUpdate('DELETE FROM account WHERE name = ?', [name]);<br>name='Apache';<br>sql.execute('DELETE FROM account WHERE name=:name', ['name':name]);<br>println('Delete After:');<br>sql.eachRow('SELECT id, name, url FROM account') { row-><br> printf('|%d|%s|%s|\n', row.id, row.name, row.url);<br>}<br></span>
8.使用DataSet來處理數據
DataSet是Sql類的直接子類,用DataSet來操作數據庫表更加有操作對象的樣子。
<span style="font-family:'宋體', SimSun;font-size:16px;">def account=sql.dataSet('account');<br><br>account.add([id:103, name:'h2', url:'http://h2.org']);<br><br>name='51cto';<br>url='http://www.51cto.com';<br>account.add([id:104, name:name, url:url]);<br><br>println('DataSet Update After');<br>account.eachRow('SELECT id, name, url FROM account') { row-><br> printf('|%d|%s|%s|\n', row.id, row.name, row.url);<br>};<br>def accountRows=account.rows();<br>accountRows.each { row-><br> printf('|%d|%s|%s|\n', row.id, row.name, row.url);<br>}<br></span>
如上dataSet的參數account表示數據庫中的表名。account是一個DataSet類型的對象,通過add方法想數據庫表中添加一條記錄,通過rows方法返回數據庫表中的所有記錄,如果rows方法添加參數則可以實現分頁的功能。
上面通過groovy.sql包提供的API實現了數據庫的基本操作,而該包中的類的其它更多的方法能夠實現更豐富的操作。下面介紹數據庫表和對象的映射操作以及集成Spring來操作數據庫表。 數據庫表和對象的映射操作:
1.準備工作
創建一個抽象的類SqlQuery
<span style="font-family:'宋體', SimSun;font-size:16px;">import groovy.sql.*;<br><br>abstract class SqlQuery {<br><br> def sql;<br> def query;<br><br> def SqlQuery(sql,query){<br> this.sql=sql;<br> this.query=query;<br> }<br><br> def execute(){<br> def rowList=sql.rows(query);<br> def results=[];<br> def size=rowList.size();<br> 0.upto(size-1) { index-><br> results <<this.mapRow(rowList[index]);<br> }<br> return results;<br> }<br><br> def abstract mapRow(row);<br>}<br></span>
創建一個Account類,其屬性對應account表的字段
<span style="font-family:'宋體', SimSun;font-size:16px;">class Account {<br><br> def id;<br> def name;<br> def url;<br><br> @Override<br> public String toString() {<br> return "|$id|$name|$url|";<br> }<br>}<br></span>
創建一個AccountQuery類繼承SqlQuery類并實現其中的抽象方法rowMap
<span style="font-family:'宋體', SimSun;font-size:16px;">import com.demo.db.SqlQuery;<br><br>class AccountQuery extends SqlQuery {<br><br> def AccountQuery(sql){<br> super(sql, 'SELECT id, name, url FROM account');<br> }<br><br> @Override<br> public Object mapRow(Object row) {<br> //映射非常之靈活<br> //def acc=new Account(id:row.getAt('id'),name:row.getAt('name'),url:row.getAt('url'));<br> //def acc=new Account(id:row.getAt(0),name:row.getAt(1),url:row.getAt(2));<br> def acc=new Account(<br> id:row.getProperty('id'),<br> name:row.getProperty('name'),<br> url:row.getProperty('url'));<br> return acc;<br> }<br>}<br></span>
AccountQuery類實現了rowMap方法,正是該方法將對象和表記錄關聯起來的,即達到了Table - Object的映射效果。
注意:上面代碼中的注釋部分是實現同樣功能的不同寫法。
2.通過SqlQuery類來查詢account表的數據
<span style="font-family:'宋體', SimSun;font-size:16px;">//表映射對象查詢<br>def accountQuery=new AccountQuery(sql);<br>def accList=accountQuery.execute();<br>println 'Table <-> Object Query: ';<br>accList.each { acc-><br> println acc.toString();<br>}<br></span>
accList則是Account對象的一個數組集合,這樣就實現了數據庫表和對象的映射操作。
集成Spring來操作數據庫表:
1.準備工作
Spring提供了一個MappingSqlQuery類,我們可以用AccountQuery繼承該類并實行其中的rowMap方法來達到數據庫表和對象的映射。
<span style="font-family:'宋體', SimSun;font-size:16px;">import com.demo.db.Account;<br><br>import org.springframework.jdbc.object.MappingSqlQuery<br><br>class AccountQuery extends MappingSqlQuery {<br><br> def AccountQuery(ds){<br> super(ds,'SELECT id, name, url FROM account');<br> this.compile();<br> }<br><br> @Override<br> protected Object mapRow(ResultSet rs, int rowNumber) throws SQLException {<br> def acc=new Account(<br> id:rs.getInt('id'),<br> name:rs.getString('name'),<br> url:rs.getString('url'));<br> return acc;<br> }<br>}<br></span>
需要注意的地方是Spring的MappingSqlQuery類的帶參數構造方法需要提供一個DataSource對象和查詢的SQL命令。
創建一個Account類的DAO類,AccountDAO來實現數據庫的操作,可以定義一個接口,然后另外實現該接口。應用程序操作數據庫則只需要依賴定義的接口即可。這里省略了接口的定義。
<span style="font-family:'宋體', SimSun;font-size:16px;">class AccountDao {<br><br> def ds;<br><br> def getAccounts(){<br> def aq=new AccountQuery(ds);<br> return aq.execute();<br> }<br>}<br></span>
AccountDao有一個getAccounts方法,通過該方法則可以獲取到表account的所有記錄,通過AccountQuery的Mapping映射,將返回一個集合對象。
2.通過AccountDao類操作數據庫
<span style="font-family:'宋體', SimSun;font-size:16px;">//集成Spring<br>def ds=new DriverManagerDataSource(db.url, db.user, db.password);<br>def accountDao=new AccountDao(ds:ds);<br>accLists=accountDao.getAccounts();<br>println 'Spring MappingSqlObject Query: ';<br>accList.each { acc-><br> println acc.toString();<br>}<br></span>
至此Groovy操作數據庫就到這里了。Groovy讓Java操作數據庫變得輕巧許多,同時又沒有引入多余復雜的API負擔。了解PHP的數據庫操作就能很快感受到Groovy讓Java操作數據庫不那么繁瑣了。
題外話:
很遺憾過了這么就才反映過來,應該擁抱Groovy,在經歷學習的Python,PHP和Nodejs之后,就更應該在已有的Java知識的基礎上使用這個據說是"Java時代的王儲"的動態語言。固步自封是可怕的,停留在舒適區更是后果不堪設想。放下,才能更輕松的上路,才能走的更遠。
在面對動不動就SSH, SSM,TSH,JSF等框架堆砌Java應用的時候,會有那么一個夜晚,突然累了,疲憊了。人就像一只猴子被困在囚籠里,跳著千篇一律的舞蹈騙取欣賞,有自知索然無味卻不得以為之的和這囚籠糾纏在一起,不得自己。不久,就被發展的潮流拍到沙灘,碎巖之上。
面對生產效率和機器效率之間的取舍不見得能達成一致的協議,但技術服務于生產,想法化為產品,則更需要容易表達和實現這些東西的技術,把復雜的事情簡單化應該是技術追求的目標。
posted on 2014-09-23 09:48 順其自然EVO 閱讀(1654) 評論(0) 編輯 收藏 所屬分類: 測試學習專欄 、數據庫