jini-jakarta99-blogging
[ 首頁 | 索引 | 登入 | 註冊 ]

Groovy 5 JDBC编程

ray_linn 所撰寫。最後修改者是 ray_linn 在 882 天之前。 已瀏覽 731 次。
[編輯] [附加]
与Groovy的脚本特性相适应,Groovy JDBC 包含了一个精巧简单的GroovySql API,由于使用闭包和迭代器,GroovySql 把 JDBC 的资源管理职责从开发人员转移到 Groovy 框架内,从而消除了 JDBC 编程的繁琐,使得变成人员可以把注意力放在处理查询结果上。

GroovySql 简介

在 Java 中,我们是这样利用JDBC来打印Music CD的样品:

package cc.ejb.groovy;

import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;

public class CdList { public static void main(String[] args) { Connection con = null; Statement stmt = null; ResultSet rs = null; try{ Class.forName("com.mysql.jdbc.Driver"); con = DriverManager.getConnection("jdbc:mysql://localhost:3306/samples","root", ""); stmt = con.createStatement(); rs = stmt.executeQuery("select * from cdbean"); while (rs.next()) { System.out.println("id:" + rs.getLong(1) + " artist:" + rs.getString(2) + " type:" + rs.getString(3)); } }catch(SQLException e){ e.printStackTrace(); }catch(ClassNotFoundException e){ e.printStackTrace(); }finally{ try{ rs.close(); }catch(Exception e){} try{ stmt.close(); }catch(Exception e){} try{ con.close(); }catch(Exception e){} } } }

利用迭代器和闭包,我们只需要短短的几行:

import groovy.sql.Sql

sql = Sql.newInstance("jdbc:mysql://localhost:3306/samples", "root","", "com.mysql.jdbc.Driver") sql.eachRow("select * from cdbean"){ println "id:${it.id} artist:${it.artist} type:${it.type}" }

在上面这段脚本中,你看不到try...catch,也不用捕获任何exception,甚至你不用关闭 Connection,也不用关闭 ResultSet,或者在 JDBC 编程中可以找到的任何其他熟悉的重要特性。

脚本中eachRow 方法可以当成查询结果上的迭代器。每个迭代都会执行传递进去的闭包,并在闭包中打印出每一次迭代的内容,id,artist,type等等。

为了运行上面的例子,必须将MySql JDBC Driver添加到classpath中。

执行更复杂的查询

Groovy 的 Sql 对象另外提供了 execute 和 executeUpdate 方法用于处理更复杂的数据操作(例如 insert、 update 和 delete )。

在下面的脚本中,您看到一个简单的 insert,它再次以 ${} 语法使用变量替换。这个代码只是向 cdbean 表插入一个新行。

id = 999
title ="Concept"
artist = "Nefarious"
type = "Blues"
sql.execute("insert into cdbean (id, title,artist, type, notes) values(${id},${title}, ${artist}, ${type},NULL)")

Groovy 还提供 execute 方法的一个重载版本,它接收一列值,这些值与查询中发现的 ? 元素对应。下面的例子查询了刚插入 cdbean 表中的数据。在底层,GroovySql 创建了普通 Java 语言 java.sql.PreparedStatement 的一个实例。

val = sql.execute("select * from cdbean where id = ?", [999])

更新的方式基本相同,也使用 executeUpdate 方法。executeUpdate 方法接收一列值,与查询中的 ? 元素对应。

id= 556 
artist = "Nefarious" 
sql.executeUpdate("update cdbean set id = ? where artist = ?", [id, artist])

删除实际上与插入相同,当然,语法不同,如例 9 所示。

sql.execute("delete from cdbean where id = ?" , [556])

数据集(DataSet)

构建于 GroovySql 简单性的基础之上,GroovySql 支持 DataSet 类型的概念,这基本上是数据库表的对象表示。使用 DataSet,您可以在行中遍历,也可以添加新行。实际上,用数据集是方便地表示表格的公共数据集合的方式。

但是,目前 GroovySql DataSet 类型的不足之处是它们没有代表关系;它们只是与数据库表的一对一映射。

import groovy.sql.Sql
class CdDataSetExample{
  static void main(args) {
    def sql = Sql.newInstance("jdbc:mysql://localhost:3306/samples", "root", "", "com.mysql.jdbc.Driver")
    def myCD = sql.dataSet("cdbean")
    myCD.each{ cd -> println "${cd.id}+ ${cd.title}"}
    myCD.add(id:"9999", title:"clerisy", artist:"Mary",type:"POP")
  }
}

GroovySql 的 DataSet 类型可以容易地用 each 方法对表的内容进行遍历,容易地用 add 方法添加新行,add 方法接受一个 map 表示需要的数据。

使用存储过程和负索引

存储过程调用和负索引(negative indexing)可能是数据操纵的重要方面。GroovySql 使存储过程调用简单得就像在 Sql 类上使用 call 方法一样。对于负索引, GroovySql 提供了自己增强的 ResultSet 类型,它工作起来非常像 Groovy 中的 collections。例如,如果您想获取结果集中的最后一个项目,您可以像例子 所示的那样做:

sql.eachRow("select * from cdbean where id=556"){ cd ->  println "-1  = " + cd.getAt(-2) 
//prints type
 println "2  = " + cd.getAt(3)
//prints type 
}

编写一个简单的报告应用程序

我们将利用 GroovySql 编写一个报告所需数据库统计信息的应用程序,您的目标数据库是 MySQL,它恰好支持用查询发现状态信息这一概念。以下是您有兴趣的状态信息:

  1. 运行时间。
  2. 处理的全部查询数量。
  3. 特定查询的比例,例如 insert、update 和 select。
用 GroovySql 从 MySQL 数据库得到这个信息太容易了。

import groovy.sql.Sql
class StatusReport{
  static void main(args) {
     def uptime,questions,insertnum,selectnum,updatenum
     def sql = Sql.newInstance("jdbc:mysql://localhost:3306/samples", "root", "", "com.mysql.jdbc.Driver")
     sql.eachRow("show status"){ status ->
           if(status.variable_name == "Uptime"){
                  uptime =  status[1]
           }else if (status.variable_name == "Questions"){
                  questions =  status[1]
           }
     }
     println "Uptime for Database: " + uptime
     println "Number of Queries: " + questions
     println "Queries per Minute = " + Integer.valueOf(questions) / Integer.valueOf(uptime)
     sql.eachRow("show status like 'Com_%'"){ status ->
        if(status.variable_name == "Com_insert"){
           insertnum =  Integer.valueOf(status[1])
        }else if (status.variable_name == "Com_select"){
           selectnum =  Integer.valueOf(status[1])
        }else if (status.variable_name == "Com_update"){
           updatenum =  Integer.valueOf(status[1])
        }
    }
    println "% Queries Inserts = " + 100 * (insertnum / Integer.valueOf(uptime))
    println "% Queries Selects = " + 100 * (selectnum / Integer.valueOf(uptime))
    println "% Queries Updates = " + 100 * (updatenum / Integer.valueOf(uptime))
    }
}

结束语

GroovySql 这个干净漂亮的 API 把闭包和迭代器与 Groovy 轻松的语法结合在一起,有助于在 Java 平台上进行快速数据库应用程序开发。

上一篇 >>> Groovy 4 集合

目前無回響 | 發表回響
請利用全文檢索或日期來找你想看的文章 ^^~

< August 2008 >
SunMonTueWedThuFriSat
12
3456789
10111213141516
17181920212223
24252627282930
31

歡迎來到 jini(99% jakarta) blogging
如果要加入我的 blogging 網頁
可以抓下面的小圖
jini (99% jakarta) blogging
link 是 www.softleader.com.tw:8668
alt 請寫 jini (99% jakarta) blogging

Blog 精選
>>Jakarta
>>Java Database
>>JAAS
>>Code Style
>>Groovy
>>Self Misc.

不會用 snipsnap 嗎
請查詢 snipsnap-help.

我會發言的討論版
jini in>>jsptw


我發行的電子報(Java Opensource Newspaper)
>>BIG5-Traditional Chinese Version
>>GB-Simplified Chinese Version

Users: (2)
… and 102 Guests


一群Java高手的部落格
>>JiaYun
>>jserv
>>Forth
>>Tempo
>>edwardsayer
>>swanbear
>>jini's JavaEE 5
>>雅加達爪哇咖啡北京分店

其他連結:
XHTML 1.0 validated
CSS validated
RSS 2.0 validated
powered by snipsnap
Attribution-NonCommercial-ShareAlike 1.0
Java b Blog
RSS Feed

Powered by SnipSnap 0.4.2a

snipsnap.org | Copyright 2000-2002 Matthias L. Jugel and Stephan J. Schmidt