`
yuanlanxiaup
  • 浏览: 855830 次
文章分类
社区版块
存档分类
最新评论

HsqlDb的持续化构建

 
阅读更多

在开发程序过程中,自从无意中使用了HsqlDb后,由于其速度特快,爱不释手(“不用不知道,谁用谁知道”),将原来所使用的SybaseSql Anywhere, MySql全都通通扔到了一边。在持续化构建过程中,因其尚未提供ant的第三方任务插件,因此需要清楚地了解在命令行下进行相应操作的方法,再通过<java>进行转化,进而针对其特点特作此小结。而大众化的知识,如驱动类名(org.hsqldb.jdbcDriver),如何在Java代码中进行连接,用户名(默认为”sa”)与密码(默认为””)地球人都知道,就不作详细介绍了。

1. HsqlDb自带工具

² org.hsqldb.util.DatabaseManager

² org.hsqldb.util.DatabaseManagerSwing

² org.hsqldb.util.Transfer

² org.hsqldb.util.QueryTool

² org.hsqldb.util.SqlTool

调用方法:java -cp hsqldb.jar org.hsqldb.util.DatabaseManager(hsqldb.jar的当前路径下)

2. HsqlDb的数据库

² 以文件形式存在。

² 未指定文件名时,默认为"test",会产生以下几种文件

Ø test.properties

Ø test.script

Ø test.log

Ø test.data

Ø test.backup

3. HsqlDb数据库的类型

服务器模式:允许多个连接

Server模式: jdbc:hsqldb:hsql://localhost/<dbname>

Web Server模式: jdbc:hsqldb:http://<hostname>/<dbname>

Servlet模式: 只能通过Tomcat等服务器提供服务

独占模式:只允许一个连接

jdbc:hsqldb:file:<dbname>

内存模式:存在于内存中,速度最快,但最后一个连接关闭或数据库关闭时,数据丢失。

jdbc:hsqldb:mem:<dbname>

4. HsqlDb的启动

Ø 当服务器启动时,如果在指定的路径中找不到相应的数据库名称,会自动创建数据库。

Ø 未指定路径及文件名,则在执行java命令的当前路径下创建test数据库

下面举几个例子。下载HsqlDb后,将其解压到某个文件夹下面,假设F:/temp/hsqldb。打开一个命令行窗口,执行

F: (回车)

cd F:/temp/hsqldb (回车)

将当前路径设为F:/temp/hsqldb

Ø 执行

java -classpath ./lib/hsqldb.jar org.hsqldb.Server

启动Server模式数据库,则在F:/temp/hsqldb下面新建test.lcktest.txttest.properties三个文件。此三个文件组成了名为test的数据库。

Ø 执行

java -classpath ./lib/hsqldb.jar org.hsqldb.Server -database.0 adb -dbname.0 adb

F:/temp/hsqldb下面新建adb.lckadb.txtadb.properties三个文件。其中,由-database.0指定的adb是存放数据库的文件名,由-dbname.0指定的adb是对外提供连接的数据库名称(也称为别名),可用jdbc:hsqldb:hsql://localhost/adb进行连接。

Ø 执行

java -classpath ./lib/hsqldb.jar org.hsqldb.Server -database.0 data/adb -dbname.0 adb

F:/temp/hsqldb/data下面新建adb.lckadb.txtadb.properties三个文件。如果data这个文件夹不存在,会自动创建。与上面比较,存放数据库的路径变了,但别名未变,因此,也用jdbc:hsqldb:hsql://localhost/adb进行连接。

5. 执行SQL语句

执行SQL语句时,出于安全原因,需要在用户根目录(Windows XP中是C:/Documents and Settings/<username>,注意,不是我的文档”)下面新建一个名为sqltool.rc文件。对于Server模式,其内容如下:

urlid localhost-sa

url jdbc:hsqldb:hsql://localhost/<dbname>

username sa

password

其中,urlusernamepassword是我们所熟悉的数据库连接参数,而urlid是在执行SQL语句时需要用于验证用户身份的id。此值可相对任意取,但在同一sqltool.rc文件中必须唯一。使用方法见下面。

5.1 通过命令行执行SQL语句

java -jar ./lib/hsqldb.jar --sql " INSERT INTO Person VALUES(1, ‘Mike’);select * from Person " localhost-sa

通过调用java命令,执行hsqldb.jar,将参数设为--sql,表示要执行SQL语句。SQL语句在两个以上时,用括号包围,之间以分号隔开。SQL语句之后紧跟着的就是sqltool.rc中的urlid。这里的urlid必须与sqltool.rc致时才能执行SQL语句。这样可在一定程度上防范SQL注入侵犯。

5.2 通过SQL文件执行SQL语句

java -jar ./lib/hsqldb.jar localhost-sa sample.sql

sample.sqlSQL文件名,跟在urlid之后。因其有一定特点,特列出全部内容,以便说明:

/*

$Id: sample.sql,v 1.5 2005/05/02 <time w:st="on" minute="7" hour="15">15:07:27</time> unsaved Exp $

Examplifies use of SqlTool.

PCTASK Table creation

*/

/* Ignore error for these two statements */

/c true

DROP TABLE pctasklist;

DROP TABLE pctask;

/c false

/p Creating table pctask

CREATE TABLE pctask (

id integer identity,

name varchar(40),

description varchar,

url varchar,

UNIQUE (name)

);

/p Creating table pctasklist

CREATE TABLE pctasklist (

id integer identity,

host varchar(20) not null,

tasksequence int not null,

pctask integer,

assigndate timestamp default current_timestamp,

completedate timestamp,

show bit default true,

FOREIGN KEY (pctask) REFERENCES pctask,

UNIQUE (host, tasksequence)

);

/p Granting privileges

GRANT select ON pctask TO public;

GRANT all ON pctask TO tomcat;

GRANT select ON pctasklist TO public;

GRANT all ON pctasklist TO tomcat;

/p Inserting test records

INSERT INTO pctask (name, description, url) VALUES (

'task one', 'Description for task 1', 'http://cnn.com');

INSERT INTO pctasklist (host, tasksequence, pctask) VALUES (

'admc-masq', 101, SELECT id FROM pctask WHERE name = 'task one');

commit;

说明:

Ø /* …… */包围的内容为注解部分

Ø /c true意思为,即使有错误,也是继续执行。因此,对于”DROP TABLE pctasklist”,即使pctasklist表不存在,无法删除该表而出错,也会继续执行下面的SQL语句。

Ø /c false则相反,意思为,对于下面的SQL语句,出果出错,马上终止执行。

Ø /p为打印信息,此信息在将SQL语句输出到其他文件中时,将按原文输出。

Ø 当执行到GRANT all ON pctask TO tomcat;时,由于tomcatschema(用户或用户组)不存在,出错,后面的语句将不再执行,包括最后一行commit语句。

Ø 默认情况下,SQL文本中的SQL语句在执行完毕后不会自动提交,因此需要在最后用commit;提交事务。但由于之前的SQL语句已经出错,因此这条语句在这里形同虚设,事务将回滚。

6. HsqlDb的关闭

根据5.1,在HsqlDb8.0中,可通过发送shutdownSQL语句来关闭数据库服务器:

java -jar ./lib/hsqldb.jar --sql "shutdown" localhost-sa

7. 输出结果

输出日志。我们使用上面的语句来输出报表:

java -jar ./lib/hsqldb.jar localhost-sa sample.sql > log.txt

使用”>”符号,将结果输出至当前路径的log.txt。执行终止后,log.txt的内容如下:

Continue-on-error is set to: true /* 对应于/c true */

Continue-on-error is set to: false /* 对应于/c false */

Creating table pctask /* 对应于/p */

Creating table pctasklist /* 对应于/p */

Granting privileges /* 对应于/p */

通过/o指令输出SQL查询结果。

HsqlDb/src/org/hsqldb/sample文件夹下有一sampledata.sql文件,里面存放了许多生成数据库及插入数据的语句。我们先通过它来插入记录。执行以下语句:

java -jar ./lib/hsqldb.jar localhost-sa ./src/org/hsqldb/sample/sampledata.sql

然后,在F:/temp/hsqldb文件夹下面创建一个名为querydata.sql的文件,内容如下:

/o report.txt

select * from Product;

COMMIT;

其中,在第一行的”/o report.txt”中,”/o”为输出查询结果指令,将结果存放在当前路径的report.txt中。执行下面的语句:

java -jar ./lib/hsqldb.jar localhost-sa querydata.sql

执行后,除了在屏幕输出我们想要的结果外,HsqlDb还在当前路径下生成一个report.txt文件,里面除了在屏幕上显示的结果外,还在第一行中自动加上时间及生成工具:

# Sat Apr 29 <time w:st="on" minute="26" hour="2">02:26:31 CST</time> 2006. Query output from org.hsqldb.util.SqlFile.

ID NAME PRICE

-- ----------------- -----

0 Iron Iron 5.4

1 Chair Shoe 24.8

2 Telephone Clock 24.8

……

如果以上语句再执行一遍,则会将查询结果添加到report.txt的末端,而原来的查询结果依然保留。

除了文本文件,我们还可以输出html格式的网页报表。将querydata.sql内容修改如下:

/H

/o report.html

select * from Product;

COMMIT;

“/H”指令将生成html格式的报表,而”/o”指令后面的report也相应地改成了.html文件。再次执行上面的SQL语句:

java -jar ./lib/hsqldb.jar localhost-sa querydata.sql

屏幕输出了report.html的源码,同时也生成了report.html文件。在querydata.sql文件中,我们打开了”/H”的指令,如果想把它改为默认的文本格式,再设一次”/H”就行了。

Html文件也是自动添加的格式。

可以通过”/p”指令添加表头、、”/d”指令过滤字段等。

8. Ant持续化构建

有了上面的基础,我们可以换成ant指令,以便实现持续化构建。在F:/temp/hsqldb下新建一个build.xml文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<project name="appfuse" basedir="." default="help">

<property name="hsqldb.path" value="lib/hsqldb.jar" />

<property name="database.dir" value="db" />

<property name="database.name" value="appfuse" />

<property name="database.urlid" value="localhost-sa" />

<property name="datafile.dir" value="src/org/hsqldb/sample/sampledata.sql" />

<property name="queryfile.name" value="querydata.sql" />

<property name="reportoutput.dir" value="report" />

<property name="reportfile.name" value="genreport.sql" />

<target name="help"

description="Show help information">

<echo level="info">HsqlDB Utils</echo>

<echo level="info">================================================================</echo>

<echo level="info">=> browseServer: Query HsqlDb with its DatabaseManagerSwing ==</echo>

<echo level="info">=> clean: Clean all output results ==</echo>

<echo level="info">=> help: Show this information ==</echo>

<echo level="info">=> shutdownServer: Shutdown HsqlDb Server ==</echo>

<echo level="info">=> startServer: Start HsqlDb Server in Server mode ==</echo>

<echo level="info">=> populate: Insert sample data ==</echo>

<echo level="info">=> queryData: Query data from database ==</echo>

<echo level="info">=> report: Make data report ==</echo>

<echo level="info">================================================================</echo>

</target>

<target name="startServer"

description="Start HsqlDb Server">

<echo level="info">Starting HsqlDb Server...</echo>

<java

classname="org.hsqldb.Server"

classpath="${hsqldb.path}"

fork="true"

failonerror="true">

<arg value="-database.0" />

<arg value="file:${database.dir}/${database.name}" />

<arg value="-dbname.0" />

<arg value="${database.name}" />

</java>

</target>

<target name="shutdownServer">

<echo level="info">Shutdown HsqlDb Server...</echo>

<java

jar="${hsqldb.path}"

classpath="${hsqldb.path}"

fork="true"

failonerror="true">

<arg value="--sql" />

<arg value="shutdown" />

<arg value="localhost-sa" />

</java>

</target>

<target name="browseServer"

description="Browse Database Server">

<echo level="info">Opening HsqlDb ManagerSwing...</echo>

<java

classname="org.hsqldb.util.DatabaseManagerSwing"

classpath="${hsqldb.path}"

fork="true"

failonerror="true">

<arg value="-url"/>

<arg value="jdbc:hsqldb:hsql://localhost/${database.name}" />

</java>

</target>

<target name="populate"

description="Insert sample data">

<java

jar="${hsqldb.path}"

classpath="${hsqldb.path}"

fork="true"

failonerror="true">

<arg value="${database.urlid}" />

<arg value="${datafile.dir}" />

</java>

</target>

<target name="queryData"

description="Query data from database">

<java

jar="${hsqldb.path}"

classpath="${hsqldb.path}"

fork="true"

failonerror="true">

<arg value="${database.urlid}" />

<arg value="${queryfile.name}" />

</java>

</target>

<target name="report"

description="Make data report">

<mkdir dir="${reportoutput.dir}" />

<java

jar="${hsqldb.path}"

classpath="${hsqldb.path}"

fork="true"

failonerror="true">

<arg value="${database.urlid}" />

<arg value="${reportfile.name}" />

</java>

</target>

<target name="clean"

description="Clean all outputs results">

<delete dir="${reportoutput.dir}" />

</target>

</project>

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics