qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問(wèn) http://qaseven.github.io/

          便捷輕巧的Groovy數(shù)據(jù)庫(kù)操作

          本文主要介紹Groovy對(duì)數(shù)據(jù)的CRUD操作,熟悉groovy.sql包,測(cè)試使用的數(shù)據(jù)庫(kù)是H2。
            1.數(shù)據(jù)庫(kù)連接配置
            <span style="font-family:'宋體', SimSun;font-size:16px;">//數(shù)據(jù)庫(kù)連接配置<br>def db = [<br>    url:'jdbc:h2:mem:groovy',<br>    user:'root',<br>    password:'root',<br>    driver:'org.h2.Driver'<br>];<br></span>
            2.創(chuàng)建數(shù)據(jù)庫(kù)連接,這里使用到Groovy的Sql類。
            <span style="font-family:'宋體', SimSun;font-size:16px;">//創(chuàng)建數(shù)據(jù)庫(kù)連接<br>def sql = Sql.newInstance(db.url, db.user, db.password, db.driver);<br></span>
            3.創(chuàng)建數(shù)據(jù)庫(kù)表
            <span style="font-size:14px;font-family:'宋體', SimSun;">//創(chuàng)建數(shù)據(jù)庫(kù)表<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方法執(zhí)行一條SQL命令,在數(shù)據(jù)庫(kù)groovy中創(chuàng)建了表account。
            4.向數(shù)據(jù)庫(kù)表中寫(xiě)入數(shù)據(jù),并查詢寫(xiě)入的數(shù)據(jù)
            <span style="font-family:'宋體', SimSun;font-size:16px;">//寫(xiě)入數(shù)據(jù)<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中寫(xiě)入3條數(shù)據(jù)記錄,然后查詢并遍歷出查詢結(jié)果,再這一過(guò)程中使用了Groovy的閉包特性,列表數(shù)據(jù)結(jié)構(gòu)。
            下面是查詢的結(jié)果:
            <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.查詢數(shù)據(jù)
            <span style="font-family:'宋體', SimSun;font-size:16px;">//查詢第一行數(shù)據(jù)<br>def rs=sql.firstRow('SELECT * FROM account');<br>println('Query First Row:');<br>println(rs);<br></span>
            Groovy的Sql類提供了大量的查詢方法(具體參見(jiàn)Groovy的API),上面5中的代碼是查詢第一條記錄,返回的類型是GroovyRowReasult,其實(shí)現(xiàn)了Map接口。打印輸出則是一個(gè)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.更新數(shù)據(jù)
            <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.刪除數(shù)據(jù)
            <span style="font-family:'宋體', SimSun;font-size:16px;">//刪除指定條件的數(shù)據(jù)<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來(lái)處理數(shù)據(jù)
            DataSet是Sql類的直接子類,用DataSet來(lái)操作數(shù)據(jù)庫(kù)表更加有操作對(duì)象的樣子。
            <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的參數(shù)account表示數(shù)據(jù)庫(kù)中的表名。account是一個(gè)DataSet類型的對(duì)象,通過(guò)add方法想數(shù)據(jù)庫(kù)表中添加一條記錄,通過(guò)rows方法返回?cái)?shù)據(jù)庫(kù)表中的所有記錄,如果rows方法添加參數(shù)則可以實(shí)現(xiàn)分頁(yè)的功能。
            上面通過(guò)groovy.sql包提供的API實(shí)現(xiàn)了數(shù)據(jù)庫(kù)的基本操作,而該包中的類的其它更多的方法能夠?qū)崿F(xiàn)更豐富的操作。下面介紹數(shù)據(jù)庫(kù)表和對(duì)象的映射操作以及集成Spring來(lái)操作數(shù)據(jù)庫(kù)表。 數(shù)據(jù)庫(kù)表和對(duì)象的映射操作:
            1.準(zhǔn)備工作
            創(chuàng)建一個(gè)抽象的類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>
            創(chuàng)建一個(gè)Account類,其屬性對(duì)應(yīng)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>
            創(chuàng)建一個(gè)AccountQuery類繼承SqlQuery類并實(shí)現(xiàn)其中的抽象方法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類實(shí)現(xiàn)了rowMap方法,正是該方法將對(duì)象和表記錄關(guān)聯(lián)起來(lái)的,即達(dá)到了Table - Object的映射效果。
            注意:上面代碼中的注釋部分是實(shí)現(xiàn)同樣功能的不同寫(xiě)法。
            2.通過(guò)SqlQuery類來(lái)查詢account表的數(shù)據(jù)
            <span style="font-family:'宋體', SimSun;font-size:16px;">//表映射對(duì)象查詢<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對(duì)象的一個(gè)數(shù)組集合,這樣就實(shí)現(xiàn)了數(shù)據(jù)庫(kù)表和對(duì)象的映射操作。
            集成Spring來(lái)操作數(shù)據(jù)庫(kù)表:
            1.準(zhǔn)備工作
            Spring提供了一個(gè)MappingSqlQuery類,我們可以用AccountQuery繼承該類并實(shí)行其中的rowMap方法來(lái)達(dá)到數(shù)據(jù)庫(kù)表和對(duì)象的映射。
            <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類的帶參數(shù)構(gòu)造方法需要提供一個(gè)DataSource對(duì)象和查詢的SQL命令。
            創(chuàng)建一個(gè)Account類的DAO類,AccountDAO來(lái)實(shí)現(xiàn)數(shù)據(jù)庫(kù)的操作,可以定義一個(gè)接口,然后另外實(shí)現(xiàn)該接口。應(yīng)用程序操作數(shù)據(jù)庫(kù)則只需要依賴定義的接口即可。這里省略了接口的定義。
            <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有一個(gè)getAccounts方法,通過(guò)該方法則可以獲取到表account的所有記錄,通過(guò)AccountQuery的Mapping映射,將返回一個(gè)集合對(duì)象。
            2.通過(guò)AccountDao類操作數(shù)據(jù)庫(kù)
            <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操作數(shù)據(jù)庫(kù)就到這里了。Groovy讓Java操作數(shù)據(jù)庫(kù)變得輕巧許多,同時(shí)又沒(méi)有引入多余復(fù)雜的API負(fù)擔(dān)。了解PHP的數(shù)據(jù)庫(kù)操作就能很快感受到Groovy讓Java操作數(shù)據(jù)庫(kù)不那么繁瑣了。
            題外話:
            很遺憾過(guò)了這么就才反映過(guò)來(lái),應(yīng)該擁抱Groovy,在經(jīng)歷學(xué)習(xí)的Python,PHP和Nodejs之后,就更應(yīng)該在已有的Java知識(shí)的基礎(chǔ)上使用這個(gè)據(jù)說(shuō)是"Java時(shí)代的王儲(chǔ)"的動(dòng)態(tài)語(yǔ)言。固步自封是可怕的,停留在舒適區(qū)更是后果不堪設(shè)想。放下,才能更輕松的上路,才能走的更遠(yuǎn)。
            在面對(duì)動(dòng)不動(dòng)就SSH, SSM,TSH,JSF等框架堆砌Java應(yīng)用的時(shí)候,會(huì)有那么一個(gè)夜晚,突然累了,疲憊了。人就像一只猴子被困在囚籠里,跳著千篇一律的舞蹈騙取欣賞,有自知索然無(wú)味卻不得以為之的和這囚籠糾纏在一起,不得自己。不久,就被發(fā)展的潮流拍到沙灘,碎巖之上。
            面對(duì)生產(chǎn)效率和機(jī)器效率之間的取舍不見(jiàn)得能達(dá)成一致的協(xié)議,但技術(shù)服務(wù)于生產(chǎn),想法化為產(chǎn)品,則更需要容易表達(dá)和實(shí)現(xiàn)這些東西的技術(shù),把復(fù)雜的事情簡(jiǎn)單化應(yīng)該是技術(shù)追求的目標(biāo)。

          posted on 2014-09-23 09:48 順其自然EVO 閱讀(1652) 評(píng)論(0)  編輯  收藏 所屬分類: 測(cè)試學(xué)習(xí)專欄 、數(shù)據(jù)庫(kù)

          <2014年9月>
          31123456
          78910111213
          14151617181920
          21222324252627
          2829301234
          567891011

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 乐平市| 科技| 罗甸县| 安陆市| 宁乡县| 晋宁县| 福鼎市| 潢川县| 阿克苏市| 万安县| 沙洋县| 田阳县| 青冈县| 台前县| 巴南区| 托克逊县| 北票市| 新巴尔虎左旗| 腾冲县| 十堰市| 公安县| 朔州市| 兴隆县| 中西区| 潞西市| 姜堰市| 屯留县| 海口市| 彰化市| 江油市| 无极县| 高青县| 舟曲县| 伊金霍洛旗| 宣威市| 湾仔区| 阿图什市| 五寨县| 营口市| 吉安市| 平邑县|