怎样为DB2 XML数据开发Java应用程序(一)
在本文中,我们将逐步介绍几个常见的编程场景,比如插入XML数据、查询XML和非XML数据、更新XML数据、删除XML数据和创建访问XML数据的存储过程。但是我们首先来复习一下开发任何类型的DB2数据库应用程序的几个基本指导原则。 遵循典型的编程“最佳实践” 尽管D
在本文中,我们将逐步介绍几个常见的编程场景,比如插入 XML 数据、查询 XML 和非 XML 数据、更新 XML 数据、删除 XML 数据和创建访问 XML 数据的存储过程。但是我们首先来复习一下开发任何类型的 DB2 数据库应用程序的几个基本指导原则。
遵循典型的编程 “最佳实践”
尽管 DB2 的本机 XML 支持是新的,但是好的数据库应用程序编程实践没有变。在进入 DB2 的 XML 技术的细节之前,应该牢记以下一般原则:
只寻找您需要的:如果您只需要该信息的一个子集的话,不要检索一个表的整个内容 —— 或者许多 XML 文档的整个内容。否则只会提高处理成本和降低运行时
性能。
避免重复数据库
服务器的工作:指示 DB2 根据您的需要过滤和处理数据,而不是在应用程序中做这项工作。例如,要让 DB2 按指定顺序返回结果,您不需要自己去对数据排序。类似地,要让 DB2 确保只返回独特的结果,您不需要重复检查重复值。以数据为中心的处理最好由数据库服务器而不是应用程序来完成。
使您的代码容易维护:在代码中包含注释或
Javadoc,尤其是当您的应用程序包含复杂的查询时。
仔细地考虑事务的范围:默认情况下,JDBC 将每个查询看作一个独立的事务。确定这是否适合您的需要,还要考虑您为事务定义的范围(和隔离级别)将如何影响整体并发
需求。
最小化
网络环境中的流量:如果避免应用程序和 DB2 之间不必要的数据传输,将会感受到更好的运行时性能。只检索需要的数据是做到这一点的方式之一。调用数据库存储过程也是有帮助的,这取决于您的工作的性质。
配置环境
要开发或运行处理 XML 数据的 Java 应用程序,DB2 不需要任何特殊的配置。实际上,可以通过使用自己选择的集成开发环境 (IDE) 或者从命令行直接利用支持的 Java Developer Kit (JDK),来编写、
测试和调试 Java 程序。但是因为 DB2 Viper 是随 Developer Workbench 一起发布的,所以本文中的例子使用的是 Developer Workbench 的开发环境。本节讨论如何配置 Developer Workbench,查看一些示例数据,并探讨一些也许您会感兴趣的数据库配置参数。
DB2 Developer Workbench
DB2 Developer Workbench 基于 Eclipse 3.1 平台,后者是一个可免费
下载的开放源码项目。要用该工作台编译和运行任何 DB2 XML 应用程序,需要创建一个项目并在该项目的构建路径中包含适当的 DB2 库(包括支持 DB2 的 JDBC 3.0 兼容驱动器的库)。要配置环境,需完成以下步骤:
启动 DB2 Workbench。例如,从
Windows Start 菜单,选择 DB2 > IBM DB2 Developer Workbench V9.1 > Developer Workbench。
创建一个新项目。我们最初将使用一个简单的项目。切换到 Java 透视图(Window > Open Perspective -> Java),并选择 File > New > Project。根据向导指定项目名称。对于其他项,保持默认的设置。
将 DB2 库添加到项目的构建路径。高亮显示项目,右击鼠标,并选择 Properties。选择 Java Build Path,并单击 Libraries 选项卡。添加适当的 DB2 外部 .jar 文件,比如 db2j
clearcase/" target="_blank" >cc.jar、db2jcc_
javax.jar 和 db2jcc_license_cu.jar。
可选地,为应用程序创建一个包。高亮显示项目,右击鼠标并选择 New > Package。
有关创建项目和包的详细信息,请参考在线帮助信息。
示例数据
本文中的例子使用 "Get off to a fast start with DB2 Viper"(developerWorks,2006 年 3 月)中创建的 "clients" 表。快速回顾一下,该表定义为:
清单 1. 最大宽度的示例代码清单
create table clients(
id int primary key not null,
name varchar(50),
status varchar(10),
contactinfo xml
)
图 1 展示了一个马上将插入该表的 "contactinfo" 列的示例 XML 文件。
图 1. 将插入 "clients" 表的示例 XML 数据
数据库配置参数
本文中的例子很简单,它们处理少量的 XML 数据,所以您不需要更改默认的数据库配置参数也能让它们运行。但是默认值对一些生产环境来说可能是不够的。具体来说,日志大小、Java 堆、查询语句堆和应用程序堆的设置值可能需要增加。如果这些值设置得不适当,那么运行时性能可能会很低,或者由于日志空间不够而不能将大型 XML 文档插入 DB2 表中。
可以从 DB2 Control Center(选择 Tools > Configuration Assist
ant)或 DB2 命令行处理器查看和更改 DB2 数据库配置参数。有关详细信息,请参考产品手册。
连接数据库
处理 DB2 XML 数据需要建立到包含数据的数据库的连接。关于该代码没有什么特殊的 —— 与编写到任何 DB2 数据库的连接的逻辑相同。
清单 2 包含一个 Helper 类,其中具有用于建立和关闭 DB2 数据库连接的方法。
清单 2. 用于获得和释放数据库连接的 Helper 类
public class Conn {
// for simplicity, I’ve hard-coded account and URL data.
private static String user = "user1";
private static String pwd = "mypassword";
private static String url = "jdbc:db2:test";
// this method gets a database connection
public static Connection getConn(){
Connection conn=null;
//load the appropriate DB2 driver and
//get a connection to the “test” database
try {
Class.forName("com.ibm.db2.jcc.DB2Driver");
conn = DriverManager.getConnection(url, user, pwd);
. . .
}
catch (Exception e) { e.printStackTrace(); }
return conn;
} // end getConn();
// this method closes a database connection
public static void closeConn(Connection conn){
try {
if(conn == null) { return; }
conn.close();
}
catch (Exception e) { e.printStackTrace(); }
finally {
try { conn.close();}
catch (Exception e) { }
}
}// end closeConn();
}// end class
您将在执行广泛任务(比如插入和查询 XML 数据)的应用程序中调用这些方法。
插入 XML 数据
由于最初的 XQuery 规范没有解决数据库写操作(比如插入数据),所以 DB2 依赖于熟悉的
SQL INSERT 语句来允许
程序员将新的 XML 数据写入包含 XML 列的表中。DB2 最多可存储 2 GB 格式良好的 XML 文档。
通常,Java 程序员需要将包含在文件中的 XML 数据插入到 DB2 中,尽管也可以从字符串、二进制数据(包括大对象)和 SQL 子选择语句插入 XML 数据。这里介绍了如何从文件和简单的字符串插入 XML 数据。有关其他插入场景的详细信息,请参考 DB2 Viper 手册。
DB2 Viper 也允许您插入 XML 文档时针对以前注册的 XML 模式进行验证或不进行验证。本文中的例子介绍了这两种方法。
插入文件时不进行验证
清单 3 中的 insertFile() 方法演示了如何将 XML 文件中的数据插入 "clients.contactinfo" 列。该方法首先定义几个变量供以后使用。前 3 个变量对应于 "clients" 表中的 ID、name 和 status 列。第 4 个是将要插入 "contactinfo" 列的 XML 文件的名称。为简单起见,值已经硬编码在该方法中;在生产环境中,输入值将以不同的方式获得。
在建立数据库连接之后,为 INSERT 语句创建一个简单的字符串。如您所见,它看起来与任何其他 DB2 INSERT 语句一样,并对四个输入列值使用参数标志符(marker)。INSERT 语句像平常一样准备好了,它的四个参数标志符也设置好了。要为 XML 列设置标志符,需打开一个 FileInputStream,并传递 XML 文件的位置。也获得该文件的长度,并使用该信息作为 setBinaryStream() 方法的输入。最后,执行该语句,检查错误,并关闭连接。
清单 3. 从文件插入 XML 数据
public static void insertFile(){
try {
// for simplicity, I’ve defined variables with input data
int id = 1885;
String name = "Amy Liu";
String status = "Silver";
String fn = "c:/XMLFiles/Client1885.xml";// input file
// get a connection
Connection conn = Conn.getConn();
// define string that will insert file without validation
String query =
"insert into clients (id, name, status, contactinfo) values (?, ?, ? ,?)";
// prepare the statement
PreparedStatement insertStmt = conn.prepareStatement(query);
insertStmt.setInt(1, id);
insertStmt.setString(2, name);
insertStmt.setString(3, status);
File file = new File(fn);
insertStmt.setBinaryStream(4, new FileInputStream(file), (int)file.length());
// execute the statement
if (insertStmt.executeUpdate() != 1) {
System.out.println("No record inserted.");
}
. . .
conn.close();
}
catch (Exception e) { . . . }
}
插入文件时进行验证
插入 XML 文件时进行验证只需要很少的附加编程工作。假设您已经创建并注册 "DB2 Viper 快速入门"(developerWorks,2006 年 3 月)中讨论的 ClientInfo.xsd 文件,那么您只需要修改 清单 3 中的一行代码,以指示 DB2 插入 XML 文件时进行验证。该代码涉及到 query 字符串的定义。
如 清单 4 所示,修订后的 INSERT 语句在为 XML 数据指定参数标志符之前调用 XMLValidate 函数。该函数也需要您指定将用于验证的 XML 模式标识符。在这里,引用的是前面注册的一个叫做 "user1.mysample" 的模式。
清单 4. 从文件插入 XML 数据时进行验证
String query = "INSERT INTO clients (id, name, status contactinfo)
" +"VALUES (?, ?, ?, xmlvalidate
(? according to xmlschema id user1.mysample))";
如果您的 XML 输入文件包含根据指定模式来说有效的数据,那么 DB2 就会插入行。否则,整个语句失败,不会插入该行的数据。
插入字符串时不进行验证
清单 5 中所示的 insertString() 方法展示了如何将分配给字符串变量的格式良好的 XML 文档插入 DB2 中。逻辑与前一例子中从文件插入数据时的逻辑没有太大的不同。不是使用您的准备语句的 setBinaryStream() 方法,而是使用 setString() 方法。本例中为了简单起见,xml 变量定义中的 XML 文档已经进行了硬编码。
注意:转义字符(反斜杠)包含在是 XML 文档一部分的引号之前(比如下面例子中的 XML 版本号)。
清单 5. 从字符串插入 XML 数据
public static void insertString(){
try {
// for simplicity, I’ve defined variables with input data
int id = 1885;
String name = "Amy Liu";
String status = "Silver";
String xml =
"<?xml version=\"1.0\"?>" +
"<Client>" +
"<Address> " +
"<street>54 Moorpark Ave.</street>" +
"<city>San Jose</city>" +
"<state>CA</state>" +
"<zip>95110</zip>" +
"</Address>" +
"<phone>" +
"<work>4084630110</work>" +
"<home>4081114444</home>" +
"<cell>4082223333</cell>" +
"</phone>" +
"<fax>4087776688</fax>" +
"<email>sailer555@yahoo.com</email>" +
"</Client>";
// get a connection
Connection conn = Conn.getConn();
// define string that will insert file without validation
String query =
"insert into clients (id, name, status, contactinfo) values (?, ?, ? ,?)";
// prepare the statement
PreparedStatement insertStmt = conn.prepareStatement(query);
insertStmt.setInt(1, id);
insertStmt.setString(2, name);
insertStmt.setString(3, status);
insertStmt.setString(4, xml);
// execute the statement
if (insertStmt.executeUpdate() != 1) {
System.out.println("No record inserted.");
}
. . .
conn.close();
}
catch (Exception e) { . . . }
}
插入字符串时进行验证
正如您所预期的,验证作为字符串提供的 XML 文档只需要很少的额外编程工作。实际上,只需要修改一行代码 —— query 变量的定义。只需要将 INSERT 语句更改为调用 XMLValidate 函数,就像在 清单 4 中所做的一样。
下面是修订后的语句:
清单 6. 从字符串插入 XML 数据时进行验证
String query = "INSERT INTO clients (id, name, status contactinfo)
" +"VALUES (?, ?, ?, xmlvalidate
(? according to xmlschema id user1.mysample))";
原文转自:http://www.ltesting.net