[转贴]Derby入门 —— (2) 博客分类: 编程技术 DerbyJava网络应用SQLJDBC
程序员文章站
2024-02-16 18:19:22
...
自动层叠删除
现在你有超过一万条的定单数据,你需要保证这些在数据库里的数据没有被破坏。固定这些数据是毫无疑问的。
让我举例说明一个潜在的问题,这个问题的中心是围绕在删除一个顾客后。问题就有可能会出现。
使用标准的SQL语句,只从custs表中删除顾客信息:
delete from custs where id='838';
这是从数据库中删除顾客编号为838的消费者。好极了!
如果这是你所做的,数据库的数据正式被破坏了。为什么呢?这是因为在数据库里有10定单信息没有关联到消费者!
这可能引起应用程序各种各样的错误。所有应用程序取得定单信息并尝试打印顾客信息时,都会涉及到这个异常。当你列出所有用户和他们的定单信息时,有些定单信息永远都不会显示出来。
在关系数据库管理系统的条款中,数据库引用完整性是不允许这样的情况的。这是因为一条顾客记录被删除,而没有删除相应的定单信息。
因此,我们需要这样做:
delete from custs where id='838';
delete from orders where custid='838';
而且,我们需要确保两条删除命令在同一个事务中执行。要么两条语句都执行成功,要么都执行失败。
这个称为删除层叠,因为删除顾客记录导致删除定单信息。
Derby有能力处理引用完整性。
Derby触发器
保证引用完整性的方法是定义一个触发器。一个触发器是一段代码或SQL语句,当数据发生修改或存取时,它将在数据库服务器里执行。Derby支持定义触发器(使用SQL语句或Java代码),当顾客记录被删除时,可以编码实现删除关联的定单信息。然而,在Derby里有一个更简单的方法。
它可以告诉Derby,使用标准的SQL DDL(数据定义)语句,这涉及到orders表和custs表。你也可以告诉Derby去完成自动层叠删除。
添加参考约束
要添加自动层叠删除,就要修改原始的createdb.sql里的语句。在db\ref子目录下找到createdbref.sql文件。你需要对orders表定义进行修改。添加下面兰色字体的内容:
create table orders
(id char(8) not null,
custid char(5) not null
references custs (id) on delete
cascade, total integer,
primary key(id,custid));
另外一个不同是连接数据库的URL值。这时,网络驱动器是指定的。一定要注意网络驱动器是需要用户名和密码的,默认的用户名和密码都是APP,所以URL值将修改为:
connect 'jdbc:derby:net://localhost/
vsjdb:user=APP;password=APP;';
你现在可以强行创建带参考约束的新表。确保复制createdbref.sql到你的工作目录。再次启动ij。现在,使用下面的命令可以删除所有记录并创建新表:
run 'createdbref.sql';
在创建了表后,你可以再次运行TableFiller.java文件去在表中添加10000条定单数据。使用network子目录的修改版本。在原始的TableFiller.java里修改的部分如下面兰色字体显示的:内容:
import java.sql.*;
import java.util.Properties;
public class TableFiller {
Connection conn = null;
PreparedStatement insertCust
= null;
PreparedStatement insertOrder
= null;
String driverName=
“com.ibm.db2.jcc.DB2Driver”;
String url =
“jdbc:derby:net://localhost/
vsjdb:user=APP;password=APP;”;
...
装载的驱动器将要改为网络驱动器(com.ibm.db2.jcc.DBDriver),URL值最好还是改成访问网络JDBC驱动器的值。否则,这个代码将与原始的TableFill.java文件一样。如果你要写你自己的JDBC代码,你可以设置一个string从外部文本文件里读取参数,这样你将不需要修改代码就能在嵌入式关系数据库管理系统和网络关系数据库管理系统之间转换。
多用户并发访问
现在,来关注多用户连接,在另一个控制台窗口启动ij会话,并连接到服务器使用下面的命令:
connect 'jdbc:derby:net://localhost/
vsjdb:user=APP;password=APP;';
在原始的控制台窗口,编译并运行新的TableFiller.java文件。这将创建1000个顾客记录和10000条定单记录。当这些操作执行完毕后,回到新的ij窗口并使用下面的命令:
select * from custs;
…and:
select * from orders;
当你执行这个命令的时候,你将发现所有用户和定单信息都已经被创建。网络服务器允许多用户并发访问数据。
测试层叠删除
一旦你创建了数据记录,试着在ij里执行下面的语句:
select * from custs where id='700';
接着执行下面的语句:
select * from orders where
custid='700';
你将看到顾客记录和这个顾客的10条定单信息。
现在,尝试删除顾客,使用下面的命令:
delete from custs where id='700';
这将删除用户记录,层叠将会删除关联的定单信息。现在尝试再次使用上面的select语句查看,你将发现那10条定单信息也被删除了。
写一个Derby存储过程
在实验的最后,你将用Java编程语言创建一个Derby存储过程。你也可以存储代码到存储过程进入Derby数据库内部,Derby能轻松的区分数据和代码。
该存储过程将调用deleteAll(),从它的名字可以理解到,它将删除数据库里的所有记录。在stored子目录下可以找到实现该存储过程的Java代码,它的名字为CleanTables.java。代码内容如下:
import java.sql.*;
public class CleanTables {
public static void delAll ()
throws SQLException {
Connection conn =
DriverManager.getConnection(
"jdbc:default:connection");
Statement delCusts =
conn.createStatement();
delCusts.executeUpdate(
"delete from custs");
delCusts.close();
conn.close();
return;
}
}
你可以看到,该存储程序在Java类里是一个public static的方法。JDBC连接器的内容是代码里url的值:
jdbc:default:connection
这会告诉Derby服务器提供一个默认的连接到代码。Derby将管理这些连接。实际上的语句是执行:
delete from custs;
自从层叠删除生效,删除custs表的任何数据,也将删除orders表里相关联的数据。
在Derby数据库里存储Java代码
要在Derby数据库里存入Java代码,你首先需要编译该代码并创建成JAR文件。编译CleanTables.java代码:
javac CleanTables.java
创建JAR文件:
jar cvf vsjstproc.jar *.class
或者你可以使用makejar.bat文件来完成上述操作,复制生成的vsjstporc.jar文件到工作目录。
在工作目录,你需要设置该JAR文件到数据库中。在ij中使用下面的命令(确保你的连接会话是通过网络驱动器获得的):
call sqlj.install_jar('vsjstproc.jar',
'APP.cleanTable', 0);
这个命令实际上是调用一个存储过程,它将设置vsjstporc.jar文件到数据库并为它设置是内部名cleanTable。APP引用应用程序计划。让JAR文件在数据库里是非常方便的。当你复制数据库时,这些代码将跟着被移动。
如果你需要从数据库里删除该JAR文件,你可以使用:
call sqlj.remove_jar(
'APP.cleanTable', 0);
在删除调用中仅仅需要内部名。
当把JAR设置到数据库里后,当它需要读取Java代码时,你需要告诉Derby去识别该JAR文件。这些都需要通过存储过程设置一个属性:
call syscs_util.syscs_set_database_
property('derby.database.
classpath', 'APP.cleanTable');
当装载Java类时,Derby都会查看内部的APP.cleanTable JAR文件。你最后准备定义一个名为deleteAll()的存储过程。使用下面的命令:
create procedure deleteAll() parameter
style java language java modifies
sql data external name
'CleanTables.delAll';
Derby将从APP.cleanTable JAR文件找到CleanTable类,并锁定该类的static delAll()方法。如果你需要删除该存储过程,你可以使用下面的命令:
drop procedure deleteAll;
有了该存储过程,你可以删除这两个表的所有数据,只需要简单的在ij下调用存储过程deleteAll():
call deleteAll();
在这个存储过程执行完毕后,你将发现这两个表是空的了。
结论
Derby是一个具有丰富特性的关系数据库系统,并能集成到你的项目中。
它支持嵌入式模式和客户端-服务器模式操作,它能适应部署多变的情况。它是100%用Java实现的,并与你的Java应用程序一样的享受‘随时发布’。它能快速执行和处理大量数据,同时也支持高级特性,例如引用完整性和存储项目,它以达到理想化的持久化的数据存储所必须的。最后但并不是最小,它*的Apache许可让你*的绑定它到你的产品中。
开源像矿山有很多隐藏的宝石一样。如果你没有再次关注Apache Derby,你将不会注意到有钻石的存在。
关于作者:
Sing Li:顾问,培训师和*作家,他专攻Java,web应用程序,分布式计算和对等技术。他的最近出版包括Early Adopter JXTA,Perfessional JINI和Professional Apache Tomcat,这些都是Wrox出版社出版
下载和安装Derby
你可以在incubator area of the Apache site里找到Derby
一旦你解压下载的Derby,注意你的解压目录,这是你的Derby安装目录。你需要使用这个目录去设置的你的classpath。
下载Derby JDBC的网络驱动器
为了在网络模式下访问Derby,你将需要一个JDBC网络驱动器。IBM捐赠了这个驱动器给Derby项目,但是直到写本文时,它都不是一个标准版本。
暂时,你将需要下载IBM DB2 JDBC Universal driver for Apache Derby Network Server。根据地址里的说明去设置你的classpath。