用 Apache Derby 进行开发取得节节胜利 用 Apache Derby 进行 Java 数据库开发第 3 部分.docx
- 文档编号:11611035
- 上传时间:2023-03-28
- 格式:DOCX
- 页数:15
- 大小:23.90KB
用 Apache Derby 进行开发取得节节胜利 用 Apache Derby 进行 Java 数据库开发第 3 部分.docx
《用 Apache Derby 进行开发取得节节胜利 用 Apache Derby 进行 Java 数据库开发第 3 部分.docx》由会员分享,可在线阅读,更多相关《用 Apache Derby 进行开发取得节节胜利 用 Apache Derby 进行 Java 数据库开发第 3 部分.docx(15页珍藏版)》请在冰豆网上搜索。
用ApacheDerby进行开发取得节节胜利用ApacheDerby进行Java数据库开发第3部分
简介:
了解如何从Java™程序修改ApacheDerby数据库。
本文将在本系列的前两篇文章基础上演示如何创建和删除表以及如何从Java应用程序中插入、更新和删除ApacheDerby数据库中的数据。
这包括使用JDBCStatement和PreparedStatement类,以及使用SQL批处理以获得改进的性能。
简介
本系列的上一篇文章“用ApacheDerby进行Java数据库开发,第2部分”(developerWorks,2007年1月),向您展示了如何使用JavaStatement对象在ApacheDerby数据库中执行SQLSELECT查询。
按照设计,查询将返回满足查询条件的行集。
因此,使用Statement对象的executeQuery方法来执行查询;此方法将把行集作为JavaResultSet对象返回。
但是很多SQL语句,例如SQL数据定义语言(DataDefinitionLanguage,DDL)命令,都不返回行集。
相反,它们执行操作,例如创建表或插入、更新或删除行。
这些操作将返回一个整型值,该值将把操作的结果编码,例如插入或删除了多少行或者错误的可能性。
对于SQLDDL操作(如清单1所示),操作成功则返回数为零。
有关将ApacheDerby数据库与SQLDDL语句结合使用的更多信息,请阅读本系列的第三篇文章。
.
清单1.处理SQLDDL语句
...
publicclassBuildSchema{
...
privatestaticfinalStringdropProductsSQL="DROPTABLEbigdog.products";
privatestaticfinalStringcreateProductsSQL=
"CREATETABLEbigdog.products("+
"itemNumberINTNOTNULL,"+
"priceDECIMAL(5,2),"+
"stockDateDATE,"+
"descriptionVARCHAR(40))";
privatestaticfinalStringproductsQuerySQL=
"SELECTitemNumber,price,stockDate,descriptionFROMbigdog.products";
staticintprocessStatement(Stringsql)throwsSQLException{
Statementstmt=con.createStatement();
intcount=stmt.executeUpdate(sql);
stmt.close();
return(count);
}
...
publicstaticvoidmain(String[]args){
try{
Class.forName(driver);
con=DriverManager.getConnection(url);
...
processStatement(dropProductsSQL);
processStatement(createProductsSQL);
doProductsQuery(productsQuerySQL);
}catch(SQLExceptionse){
printSQLException(se);
}
...
就像本文中提供的其他Java代码一样,此示例是在上一篇文章的ThirdQuery示例的基础上构建的。
因此,您在这里只看到了部分代码清单(完整的代码可在下载部分的压缩文件中获得)。
在本例中,首先定义了几个JavaString对象,这些对象中包含删除和创建您在本系列中一直在使用的bigdog.products表的SQL代码。
然后定义一个新方法processStatement,该方法用于处理通过使用Statement对象的executeUpdate方法提供的所有适用的SQL语句。
此方法仅可用于不返回数据的SQL操作,例如SQLDDL或SQLINSERT、UPDATE或DELETE操作。
此方法将把SQL发送给ApacheDerby数据库,将在其中处理SQL并返回整型值。
就SQLDDL操作来说,返回数为零,因此可以在这个介绍性示例的main方法中忽略它。
在实践中,应当检验该值以防止在尝试在更复杂的模式中使用数据时遇到错误情况。
要运行本文中提供的Java程序,需要具有一个干净的工作环境。
您可以遵循清单2中显示的指引完成该过程,也可以重用在上一篇文章中配好的现有的测试数据库。
清单2.通过Java修改数据库模式
rb$mkdirderbyWork
rb$cdderbyWork
rb$unzip../derby11.zip
Archive:
../derby11.zip
inflating:
BuildSchema.java
inflating:
derby.build.sql
inflating:
FirstInsert.java
inflating:
FirstUpdate.java
inflating:
SecondInsert.java
inflating:
ThirdInsert.java
rb$javaorg.apache.derby.tools.ij ijversion10.2 ... ij> rb$javac*.java rb$javaBuildSchema ITEMNUMBER|PRICE|STOCKDATE|DESCRIPTION ------------------------------------------------------------------------ 0rowsselected 升级ApacheDerby数据库 您可能注意到了清单2中显示的Apache数据库版本是10.2。 当新版本数据库发布后,数据库管理员必须谨慎。 执行任何升级都应当慎重,遵循经过良好定义的移植路线,并进行足够的回归测试来检验关键的商业应用程序的准确性。 但是,出于本系列文章的目的,您可以将此注意事项抛在脑后。 这个新版本有很多附加功能和若干个错误修正,使您可以轻松决定进行升级。 以下步骤十分简单: 1.创建一个干净的工作目录,然后将示例代码展开到这个新目录中。 2.使用ApacheDerbyij工具执行附带的ApacheDerby脚本文件。 3.编译本文附带的所有Java代码,然后执行BuildSchemaJava程序。 正如您可以在示例输出中看到的,BuildSchema类将先删除然后再重新创建bigdog.products表,提供一张新表供您将新数据插入到其中。 如果在使用ij工具或者编译或执行任何Java类时遇到错误,最可能的元凶是JavaCLASSPATH环境变量。 确保此变量包含必需的ApacheDerbyJAR文件,方法是使用echo$CLASSPATH命令显示这个变量的值;该命令应当会生成类似如下所示的输出(注: ApacheDerby安装可能会略微更改这些值): /opt/Apache/db-derby-10.2.1.6-bin/lib/derby.jar: /opt/Apache/db-derby-10.2.1.6-bin/lib/derbytools.jar: .。 回页首 数据修改语句 以上示例使用CREATE和DROP之类的SQLDDL语句修改了bigdog模式。 您可以使用类似的过程使用SQLINSERT语句插入新行,如清单3所示。 清单3.处理SQLINSERT语句 ... publicclassFirstInsert{ ... privatestaticfinalStringinsertProductsSQL= "INSERTINTObigdog.products(itemNumber,price,stockDate,description)VALUES"; privatestaticfinalString[]productsData= {"(1,19.95,'2006-03-31','Hoodedsweatshirt')", "(2,99.99,'2006-03-29','Beachumbrella')", "(3,0.99,'2006-02-28','')", "(4,29.95,'2006-02-10','Malebathingsuit,blue')", "(5,49.95,'2006-02-20','Femalebathingsuit,onepiece,aqua')", "(6,9.95,'2006-01-15','Childsandtoyset')", "(7,24.95,'2005-12-20','Whitebeachtowel')", "(8,32.95,'2005-12-22','Blue-stripebeachtowel')", "(9,12.95,'2006-03-12','Flip-flop')", "(10,34.95,'2006-01-24','Open-toedsandal')"}; privatestaticfinalStringproductsQuerySQL= "SELECTitemNumber,price,stockDate,descriptionFROMbigdog.products"; ... publicstaticvoidmain(String[]args){ ... intnumRows=0; for(Stringproduct: productsData){ numRows+=processStatement(insertProductsSQL+product); } System.out.println("\n"+numRows+ "rowsinsertedintobigdog.productstable."); doProductsQuery(productsQuerySQL); ... 显式查询: 最佳实践 在清单3的SQLINSERT语句中,显式列出了列名(itemNumber、price等等)。 虽然可以省去这些列名,但是不建议这样做: 如果其他人意外地(例如重命名、添加或删除列)修改了模式,则代码将暴露于意料之外甚至可能无提示的错误之下。 通过显式列出列的名称和序号,可将遇到此类错误的风险减至最低。 在这个FirstInsertJava程序中,SQLDDL语句被替换成了SQLINSERT语句,后者被修改为在调用processStatement方法之前先添加两个JavaString对象来包含适当的产品数据。 在这种情况下,每一行数据都是单独插入的,并且需要累计processStatement方法返回的行数才能确定在数据库中总共插入了多少行。 此操作将把相同的10行插入在本系列的前面几篇文章中添加的bigdog.products表中,但是在这种情况下,它每次只能插入一行。 您可以转而编写一个大型字符串尝试一次插入所有数据——在这种情况下为全部的10行。 但是,这样做不是个好主意,原因有两个: ∙通过一次插入一行,可对数据库中的数据进行更高级别的控制。 如果一行插入失败,则在只处理一行的情况下更易于跟踪问题。 ∙使用单个大型JavaString插入大量行难于处理并且导致代码更加难以维护。 注: 不建议在实践中按照这种方式集中添加多个JavaString对象;相反,应当使用StringBuffer。 但是,出于本文的演示目的,可以遵循这种更简单的方法。 要运行这段Java代码,请执行FirstInsertJava程序。 这样做将用10个新行填充bigdog.products表,10个新行如清单4所示。 清单4.使用Java代码插入数据 rb$javaFirstInsert 10rowsinsertedintobigdog.productstable. ITEMNUMBER|PRICE|STOCKDATE|DESCRIPTION ------------------------------------------------------------------------ 1|19.95|2006-03-31|Hoodedsweatshirt 2|99.99|2006-03-29|Beachumbrella 3|0.99|2006-02-28| 4|29.95|2006-02-10|Malebathingsuit,blue 5|49.95|2006-02-20|Femalebathingsuit,onepiece,aqua 6|9.95|2006-01-15|Childsandtoyset 7|24.95|2005-12-20|Whitebeachtowel 8|32.95|2005-12-22|Blue-stripebeachtowel 9|12.95|2006-03-12|Flip-flop 10|34.95|2006-01-24|Open-toedsandal 10rowsselected 回页首 准备语句 在上一部分中,您通过创建包含适当的SQLINSERT语句的JavaString把10行数据插入到了ApacheDerby数据库中。 这种方法虽然起作用,但不是最佳方法,因为它要求在每次需要调用JavaStatement对象的executeUpdate方法时都必须创建一个新的静态INSERT语句。 更有效的方法是把基本的INSERT语句发送给数据库,然后根据需要单独传递每个新行的相关数据。 通过这种方法,可以让数据库以Java编译程序处理Java函数的同一种方式准备SQL语句。 依此类推,随后可以将新参数传递到这个准备好的SQL语句进行处理。 由于这种方法可以带来显著的性能加速,因此JDBC规范提供了PreparedStatement类允许用不同的输入参数多次执行SQL操作。 动态SQLINSERT语句 由于提供的功能不同,因此使用PreparedStatement不同于使用Statement。 首先,需要使用问号字符(? )来指示提供输入参数的位置,修改基本的SQLINSERT语句。 例如,VALUES(? ? ? ? )指示将提供四个输入参数以完成SQLINSERT语句的VALUES子句。 将这个修改过的String作为输入传递给Connection对象的prepareStatement方法,该方法将允许ApacheDerby数据库预编译SQL进行更快速的处理。 其次,必须为每个输入参数提供值。 通过对每个输入参数调用setXXX方法可完成此操作。 关于此类方法,有两个要点十分重要: ∙XXX是由发送给数据库的参数的数据类型替换的;例如,setInt表示发送的是整数,而setDate表示发送的是Date对象。 ∙这些方法将获取两个参数: 输入参数的序号和要使用的实际值。 通过包括指示正在设定的输入参数的序数值,您不必以特定顺序设定输入参数。 虽然使用PreparedStatement可能听起来让人糊涂,但是它实际上十分简单,如清单5所示。 清单5.将准备好的语句用于SQLINSERT操作 ... publicclassSecondInsert{ ... privatestaticfinalStringinsertProductsSQL= "INSERTINTObigdog.products(itemNumber,price,stockDate,description)"+ "VALUES(? ? ? ? )"; privatestaticfinalint[]itemNumbers={1,2,3,4,5,6,7,8,9,10}; privatestaticfinalBigDecimal[]prices= {newBigDecimal(19.95),newBigDecimal(99.99),newBigDecimal(0.99), newBigDecimal(29.95),newBigDecimal(49.95),newBigDecimal(9.95), newBigDecimal(24.95),newBigDecimal(32.95), newBigDecimal(12.95),newBigDecimal(34.95)}; privatestaticfinalDate[]dates= {Date.valueOf("2006-03-31"),Date.valueOf("2006-03-29"), Date.valueOf("2006-02-28"),Date.valueOf("2006-02-10"), Date.valueOf("2006-02-20"),Date.valueOf("2006-01-15"), Date.valueOf("2005-12-20"),Date.valueOf("2005-12-22"), Date.valueOf("2006-03-12"),Date.valueOf("2006-01-24")}; privatestaticfinalString[]descriptions= {"Hoodedsweatshirt","Beachumbrella","","Malebathingsuit,blue", "Femalebathingsuit,onepiece,aqua","Childsandtoyset", "Whitebeachtowel","Blue-stripebeachtowel","Flip-flop", "Open-toedsandal"}; privatestaticfinalStringproductsQuerySQL= "SELECTitemNumber,price,stockDate,descriptionFROMbigdog.products"; ... staticvoidinsertData(Stringsql)throwsSQLException{ intnumRows=0; PreparedStatementstmt=con.prepareStatement(sql); for(intitemNumber: itemNumbers){ stmt.setInt(1,itemNumbers[itemNumber-1]); stmt.setBigDecimal(2,prices[itemNumber-1]); stmt.setDate(3,dates[itemNumber-1]); stmt.setString(4,descriptions[itemNumber-1]); numRows+=stmt.executeUpdate(); } System.out.println("\n"+numRows+ "rowsinsertedintobigdog.productstable."); stmt.close(); } publicstaticvoidmain(String[]args){ ... insertData(insertProductsSQL); doProductsQuery(productsQuerySQL); ... 这段示例代码开始时先定义包含待插入数据的Java数组。 虽然这是一种有用的演示策略,但是在生产环境中最有可能从文件中读入这些数据或者检索作为计算结果的这些数据,或者这些数据来自用户的输入。 其他修改基本上与将代码从使用Statement对象更改为使用PreparedStatement对象相关。 这包括: ∙创建PreparedStatement对象。 ∙设定相关的输入参数,这些输入参数包括Javaint、BigDecimal、Date和String。 ∙使用executeUpdate方法执行INSERT语句。 要看到此概念起作用,首先需要清空现有的bigdog.products表,通过运行BuildSchema程序可以轻松地完成此操作,然后运行SecondInsert程序,如清单6所示(注: 此代码清单中的输出经过了压缩以节省空间)。 清单6.执行Java准备好的INSERT语句 rb$javaBuildSchema ITEMNUMBER|PRICE|STOCKDATE|DESCRIPTION ------------------------------------------------------------------------ 0rowsselected rb$javaSecondInsert 10rowsinsertedintobigdog.productstable. ITEMNUMBER|PRICE|STOCKDATE|DESCRIPTION ------------------------------------------------------------------------ 1|19.94|2006-03-31|Hoodedsweatshirt ... 10|34.95|2006-01-24|Open-toedsandal 10rowsselecte
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Apache Derby 进行开发 取得节节胜利 进行 Java 数据库开发第 部分 开发 取得 节节胜利 数据库
链接地址:https://www.bdocx.com/doc/11611035.html