[转载]学习如何用 Jython 编写 DB2 JDBC 工具

学习如何用 Jython 编写 DB2 JDBC 工具


您希望降低用 DB2 UDB JDBC 编写的工具的开发和维护成本吗?在这篇文章中,Victor Yang 解释了如何借助 Jython 来做到这一点。

简介

DB2 ®Universal Database ™(UDB)JDBC 驱动程序已被证明是一种强大的,并且得到 IBM 支持的技术。Jython 是 Python 编程语言百分之百的纯 Java 实现(请参阅 参考资料)。

首先,我们将告诉您 Jython 为何在编写 DB2 JDBC 工具方面功能强大、使用方便且充满乐趣。然后,我们将展示如何安装带有 DB2 JDBC 驱动程序的 Jython。最后,我们将演示几个查询示例,以及一个在 Jython 中使用批量插入的 QA 工具。


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


为何使用 Jython?

以下是 Neo 的一个真实故事。Neo 是全职的服务器端 Java 开发人员。他使用 Python 编写实用程序,例如解析 XML 或通过 HTTP 协议连接充当信用卡网关和订单履行网关的 Web 服务。因为 Python 的类型是动态的,且具有简洁的数据结构语法,比如列表和字典,所以 Neo 发现它通常可以减少代码行。

Neo 在处理一个股票交易应用程序,该应用程序是用部署在 AIX 上的 WebSphere Application Server 5.x 和 DB2 8.x 构建的。在实时系统中,每隔几分钟就要向表 STOCKQUOTE 输入 10,000 条 XML 格式的记录,以更新股票行情。执行批量输入的代码是作为另一系统的组成部分而由另一团队完成的,所以他无法获得源代码。此外,STOCKQUOTE 上有一个触发器,一旦股票价格下跌至一个预定义的阈值如 $10,该触发器就发出警报。项目经理给 Neo 分配了任务,让他用 Mercury Interactive 的 LoadRunner 或 Segue 的 SilkPerformermeasure 等自动化加载测试工具,测量在批量输入的情况下触发器所带来的性能影响。因此,Neo 需要编写一个批量输入的仿真器(simulator),用于模拟向 STOCKQUOTE 表加载 10,000 行记录。

开始,Neo 希望用纯 java JDBC 编写该仿真器,但是冗长的类型声明、编辑/编译/测试周期将占用他大量宝贵的开发时间。而且,因为 Python 的效率收益过去给 Neo 留下了深刻印象,所以他想是否可以用 Python 编写代码来使用 DB2 JDBC 驱动程序。如果可行,他就可以在几小时之内,用 Python 整洁的列表和字典等数据结构,以及列表理解(list comprehension)等整洁的函数编程功能来编写这个代码。在进行一些研究之后,他发现 Jython 十分方便,且正适合该工作。因为十分熟悉 DB2 JDBC 的编程,并拥有 Jython 参考资料,所以 Neo 在几小时之内就编写并测试了批量插入仿真器。他十分惊讶于 Jython 的强大功能,Jython 中包含了两大最佳领域:巨大的 Java 库和整洁的 Python 功能。因此,批量输入仿真器的最终代码比用纯 Java JDBC 所编写的源代码要少很多。源代码的总量影响很大,因为它可以减少程序员在编程时需要处理的细节。因此,降低源代码量将减小软件的复杂性,从而节省成本。


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


Jython JDBC 安装

安装 Jython 2.1

为了运行本文中的示例,您需要安装 Jython 2.1 和 JVM。您可以从 Jython 主页(请参阅 参考资料)获得 Jython。如果将 Jython 安装路径添加到平台上的 PATH 环境变量中,安装就十分方便。

Charming Jython(请参阅 参考资料)也包含了安装 Jython 的章节。

启用 DB2 UDB V8 中的 SAMPLE 数据库

本文所展示的示例使用了 SAMPLE 数据库。既可以通过运行与 DB2 一起发布的 db2sampl 程序来创建 SAMPLE 数据库,也可以从 DB2 安装工具菜单中的 FirstSteps 来创建。此外,还必须创建 DB2 ID/口令。本文中,我们使用 vyang/jythonrocks。

如何在 Jython 中连接 SAMPLE 数据库

这里,我们将展示如何在 Jython 中用流行的 type 2 和 type 4 驱动程序连接 SAMPLE 数据库。关于所有 JDBC 驱动程序的详细描述,请参阅 参考资料


Type 2 JDBC 驱动程序(CLI JDBC 驱动程序)
 from java.lang import * 
 from java.sql import * 
 Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").newInstance() 
 con = DriverManager.getConnection( 'jdbc:db2:sample','vyang','jythonrocks')


Type 4 JDBC 驱动程序(DB2 UDB V8 中新增的)

from java.lang import * 
from java.sql import * 
Class.forName("com.ibm.db2.jcc.DB2Driver").newInstance()
con = DriverManager.getConnection( 'jdbc:db2://db2host:50000/sample','vyang','jythonrocks') 

除了以下几点之外,以上连接 SAMPLE 数据库的代码看上去与 JDBC java 代码十分相似:

  • Jython 需要导入每一个 Java 包,包括 java.lang。
  • Jython 字符串可以使用单引号,也可以使用双引号。
  • Jython 的类型是动态的,因此不需要将 con的类型声明为 java.sql.Connection。

blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


查询示例

现在,我们已经知道如何安装 Jython 和连接 DB2,应该开始查看示例了。下列示例在 Windows 2000 上使用 SAMPLE 数据库和 type 2 CLI JDBC 驱动程序。您可以从本页底部的下载小节中下载这些示例。

一个简单的动态查询(select1.jy)

select1.jy 将按升序从 EMPLOYEE 表(包含在 sample 数据库中)中选出所有薪水超过 $20,000 的雇员。

从命令控制台“jython select1.jy”运行 select1.jy。


图 1. “jython select1.jy”的输出
select1.jpg

以下是 Jython 代码。


清单 1. select1.jy
from java.lang import *
from java.sql import *
# load DB2 JDBC type 2 driver (app driver)
Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").newInstance()
con = DriverManager.getConnection( 'jdbc:db2:sample','vyang','jythonrocks')
stmt = con.createStatement()
sql='select firstname,lastname,salary from employee where salary > 20000 order by salary' 
rs = stmt.executeQuery(sql)
employeeList=[]
while (rs.next()):
    row={}
    row['firstname']=rs.getString(1)
    row['lastname']=rs.getString(2)
    row['salary']=rs.getDouble(3)
    employeeList.append(row)
    
rs.close()
stmt.close()
con.close()
print 'employee salary over $20,000'
print '============================'
print 'firstname lastname salary'
print '============================'
# print the result 
for e in employeeList:
    print e['firstname'],e['lastname'],'$'+ str(e['salary']) 
 

以上代码在概念上与纯 Java JDBC 编程极其相似。但是,如果仔细查看,就会发现用 Jython 编写的代码更少一些。

注意:

  • 无需为 Connection、Statement、Result 声明类型,虽然这在纯 Java JDBC 编程中是必要的。它们的类型是动态解析的。
  • 对于结果集处理,与 java.util 中的 Vector/ArrayList 相比,使用 employeeList(Jython 列表)和 row(Jython 字典)来保存 java.sql.ResultSet 要容易得多。
  • 对于 employeeList 内容的输出,最后的 2 行代码就可以很好地完成。

SQL 字符串的格式化(select2.jy)

运行“jython select2.jy”。其功能与 select1.jy 相当。惟一的区别就是它使用 Jython 字典来保存 String 模板里的名称-值对,并使用 % 运算符来将该模板转换为有意义的 SQL 字符串。

基于 Jython 内置字典的字符串格式化与 C 中 printf 的一样强大,我们可以使用 % 运算符来关联字典。设想如果用 Java 来实现会怎样。

下列代码的结果是“select firstname,lastname,salary from employee where salary > 20000 order by salary”,与 select1.jy 中的完全一样。


清单 2. (select2.jy)基于字典的 SQL 字符串格式化
sqlTemplate = 'SELECT %(columns)s FROM %(tables)s WHERE %(constraints)s' 
dict = {'columns':      'firstname,lastname,salary',
        'constraints' : 'salary>20000',
        'tables' :      'employee'}
sql = sqlTemplate % dict
print sql

函数风格的结果集处理(select3.jy)

我们需要将结果写入文件中,以便进一步进行分析。为了说明如何在这里使用 Jython 的函数编程功能,下列代码中使用了 lambda 函数和列表理解,虽然也可以用命令式(imperative)编程风格来完成。


清单 3. (select3.jy)使用 lamda 和列表理解
# lambda function
toStr=lambda e: e['firstname']+','+e['lastname']+',$'+ str(e['salary'])
# an example of list comprehension
# write the result into a file called "salaries.txt"
print '======================================'
print 'the results are saved in salaries.txt'
print '======================================'
try:
    f=open('salaries.txt','w')
    f.writelines([toStr(e)+'
' for e in employeeList])
finally:
    f.close()

注意:

  • 一般来说,lambda 函数接收任何数目的参数,并返回单个表达式的值。它类似于 Java 中的匿名类,除了它是一个可在需要时作为参数来传递的第一级对象之外。Lambda 函数 toStr() 将为输出转换雇员的值(作为一个字典)。
  • ([toStr(e)+' ' for e in employeeList]) 通过 Jython 的列表理解,用 lambda 函数 toStr 将每个结果变成 slaries.txt 中的一行。将之与通过循环编写的等效代码进行比较。
  • Jython 中文本文件的处理只有简单的三行代码:open()、readlines/writelines (taking a list) 和 close()。再次设想如果用 java.io 编写会怎样。

获取图形(select4.jy)

让我们来尝试用 HTML 显示结果。还可以用红色突出显示薪水超过 $40,000 的那些雇员。

本示例中,我们使用 SWT。SWT 是一种软件组件,它以一种与操作系统无关的方式为 Eclipse 平台交付原生窗口部件(native widget)功能。这就是使 IBM WSAD(Websphere Studio Application Developer)以本机代码的速度运行的秘诀。


图 2. “select4.bat”的输出
swt.jpg

清单 4 展示了需要从 SWT 导入的包。


清单 4. (select4.jy)导入 SWT 包
from org.eclipse.swt import *
from org.eclipse.swt.graphics import *
from org.eclipse.swt.layout import *
from org.eclipse.swt.widgets import *
from org.eclipse.swt.browser import *

清单 5 展示了如何使用 SWT 显示 HTML 格式的结果。


清单 5. (select4.jy)显示 HTML 格式的结果
# display in browser with HTML
display = Display()
shell = Shell (display)
shell.setLayout(FillLayout())
browser = Browser(shell, SWT.NONE)
browser.setText(toHtml(employeeList))
browser.setSize(400,500)
shell.pack()
shell.open()
while not shell.isDisposed():
    if not display.readAndDispatch():
        display.sleep
display.dispose()

注意:

  • 该代码片断几乎与用于 SWT 应用程序的一模一样。
  • 对于格式化 HTML,我们在 Jython 函数 toHtml(employeeList) 中使用基于元组的字符串格式化,该函数将 employeeList 变成 HTML 格式的字符串。

blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


有意思的插入

现在,我们将看到如何在 Jython 中进行插入。

假定 Joe 是一名 QA,他需要为功能测试在 SAMPLE 数据库中创建新的雇员。在 Jython 中,Joe 进行少量工作就可以编写他自己的脚本。

例如,Joe 可以在 SAMPLE 数据库中通过运行“jython batchinsert.jy joescript.txt”,创建三名新雇员。


清单 6. joescript.txt
createEmployee(firstName='JOHN',midinit='M',lastName='DOE',salary=32888.55,sex='M',workdept='A01',
job='DESIGNER')
createEmployee(firstName='MANAGER',midinit='M',lastName='DOE',salary=50000,sex='M',workdept='A01',
job='MANAGER')
createEmployee(firstName='SARA',midinit='M',lastName='DOE',salary=40000,sex='F',workdept='C01',
job='DESIGNER')

如果 Joe 想要添加另一名 Employee,就只需用他喜欢的文本编辑器编辑“joescript.txt”。

脚本背后的功能十分简单。Jython 有一个名为 execfile(filename) 的内置函数。如果我们将 createEmployee() 实现为 Jython 函数,用于向 EMPLOYEE 表插入一行记录,那么 execfile('joescript.txt') 将按照 Joe 需要的数目插入雇员。

换言之,我们利用 Jython 的解释器,并可以为 Joe 派生一个像这样的小的测试语言。该解决方案也是可扩展的。如果 Joe 需要在脚本中删除或更新雇员,就只需要添加另一函数。对于 Joe 来说,最酷的事情就是学习曲线很短。他可以立刻编写这样的脚本,而没有意识到正在进行 Jython 函数调用。


清单 7. (batchinsert.jy)createEmployee 函数
from java.lang import *
from java.sql import *
import sys
def createEmployee(**args):
    global stmt
    sqlTemplate=
    "INSERT into EMPLOYEE (EMPNO,FIRSTNAME,MIDINIT,LASTNAME,SALARY,SEX,EDLEVEL, HIREDATE, WORKDEPT,JOB) 
    values ((select RTRIM(CHAR(MAX(INT(EMPNO))+1)) from EMPLOYEE), 
    '%(firstName)s', '%(midinit)s','%(lastName)s', 
    %(salary).2f,'%(sex)s' ,18, CURRENT DATE,'%(workdept)s','%(job)s')" 
    # dictionary based SQL string formatting
    sql=sqlTemplate % args
    
    stmt.addBatch(sql)
    
# load DB2 JDBC type 2 driver
Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").newInstance()
con = DriverManager.getConnection( 'jdbc:db2:sample', 'vyang','jythonrocks');
con.setAutoCommit(0)
stmt = con.createStatement()
execfile(sys.argv[1])
stmt.executeBatch()
stmt.close()
# commit
con.commit()
con.close()

这里有许多新内容。

  • con.setAutoCommit(0) 用于关闭自动提交(auto commit),就像 JDBC 调用中的 con.setAutoCommit(false) 一样。
  • 用于成批插入的 stmt.addBatch(sql)stmt.executeBatch() 能有效地加快批量插入的速度。该技术还在 Neo 的加载仿真器中用于进行大容量的插入。
  • global stmt 将使 stmt 成为一个共享的全局变量,很适用于该环境中。
  • def createEmployee(**args) 接收参数为字典 args ,并显示 Jython 函数声明是多么灵活。
  • sql=sqlTemplate % args 使用基于字典的 SQL 字符串格式化,我们在 select2.jy 中已经了解。

blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


结束语

本文中,我们展示了一些简单示例,可作为开发人员进行探索的起点。我们相信在继续探索时,还会有更多益处和问题。

此外,Jython 得益于与巨大 Java 库以及诸如 IBM DB2 JDBC 驱动程序这样的 API 的无缝集成。基于其语言特征,Jython 非常适合于自动化测试和加载测试等任务,这些任务都需要快速的应用程序开发。正如 Charming Jython(请参阅 参考资料)中所描述的,“Jython 绝不是要您抛弃 Java 语言。Jython 会是一个非常方便的补充,对于快速检查和构造原型、测试以及处理那些比较适合使用其方法的编码任务是很有用的。”

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/374079/viewspace-130364/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/374079/viewspace-130364/

内容概要:本文针对高比例清洁能源接入背景下配电网重构的关键问题,结合需求响应机制开展深入研究,以IEEE33节点标准系统为算例,采用Matlab进行建模与仿真分析。研究充分考虑风电、光伏等分布式电源出力的不确定性特征以及需求侧响应对系统运行的影响,构建了以降低网络损耗、改善电压质量、提升清洁能源消纳能力为目标的优化模型。通过引入智能优化算法求解网络中最优的开关操作策略,实现配电网拓扑结构的动态重构,并通过仿真结果验证了所提方法在增强系统灵活性、可靠性和经济性方面的有效性与优越性。; 适合人群:具备电力系统分析、优化理论基础及Matlab编程能力,从事新能源并网、智能配电网、需求响应、分布式能源管理等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于高渗透率可再生能源接入的主动配电网运行优化;②支撑需求响应机制下电网灵活性资源的协同调控研究;③为现代低碳、高效、自愈型智能配电网的规划与运行提供技术路径与决策支持。; 阅读建议:建议读者结合文中提供的Matlab代码与IEEE33节点系统参数进行实践复现,深入掌握配电网重构的数学建模方法、约束处理技巧及智能算法求解流程,同时可进一步拓展至多目标优化、不确定性建模(如鲁棒优化、分布鲁棒优化)及动态重构等前沿方向的研究。
内容概要:本文研究了基于条件风险价值(CVaR)的虚拟电厂与电动汽车集群之间的主从博弈优化调度问题,旨在应对电力系统中可再生能源出力与负荷需求的不确定性。通过构建主从博弈模型,将虚拟电厂作为领导者制定电价策略,电动汽车集群作为跟随者响应调度指令,结合CVaR方法量化不同风险偏好的决策行为,有效提升了系统在极端场景下的鲁棒性与经济性。研究采用Matlab进行模型编程与仿真,实现了对多主体互动行为的优化调度,并通过算例验证了所提出模型在降低运行成本、提高新能源消纳能力以及增强风险管控方面的优越性能。该方法为高比例可再生能源接入背景下电力系统的协调运行提供了理论支持和技术路径。; 适合人群:具备一定电力系统、优化理论及博弈论基础知识,从事能源互联网、综合能源系统、电动汽车调度等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于虚拟电厂参与电力市场环境下的定价与调度决策;②指导大规模电动汽车集群在不确定性条件下的有序充放电管理;③为含高比例可再生能源的电力系统提供风险规避型优化调度方案。; 阅读建议:学习者应掌握Matlab编程基础,熟悉YALMIP+CPLEX等优化工具箱的使用,结合文中模型结构与代码实现,重点理解主从博弈的建模逻辑、CVaR的风险刻画机制以及多目标优化的求解流程,建议自行复现算例以加深理解。
内容概要:本文针对2MW大功率虚拟同步发电机(VSG)的惯量与阻尼特性,开展并网逆变系统的Simulink仿真研究,系统构建了VSG的核心控制模型,深入分析其在并网过程中的动态响应特性、系统稳定性以及对电网惯性和阻尼支撑能力的作用机制。研究通过仿真手段验证了VSG有效模拟传统同步发电机机械动态特性的可行性,重点探讨了惯量、阻尼等关键控制参数对系统暂态性能和抗扰动能力的影响规律,旨在为提升高比例新能源接入背景下电力系统的频率稳定性和电压支撑能力提供有效的技术路径与仿真依据。; 适合人群:具备电力电子、电力系统分析及自动控制理论基础,从事新能源并网技术、微电网控制、虚拟同步机(VSG/VSM)等领域研究的研究生、科研人员及电力系统相关工程技术人员。; 使用场景及目标:①深入理解虚拟同步发电机模拟传统同步机转动惯量与阻尼的物理机理与数学建模方法;②掌握利用Simulink搭建VSG并网逆变器详细仿真模型的关键技术;③通过仿真分析惯量和阻尼系数对系统动态响应(如频率波动、功率振荡)的影响,实现控制器参数的优化设计;④为解决弱电网条件下新能源并网的稳定性问题提供仿真验证平台和技术参考。; 阅读建议:学习者应熟练掌握Simulink/Matlab仿真环境,建议结合文中所述的VSG控制策略与系统拓扑结构,动手复现完整的仿真模型,并通过设置不同工况(如负载突变、电网电压波动)和调整控制参数,对比观察系统响应曲线,从而深刻理解VSG的控制特性、优势及其在现代电力系统中的应用价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值