发新话题
打印

[Database] 嵌入式数据库HSQLDB

嵌入式数据库HSQLDB

数据库环境配置和使用
" m. t0 N6 @  T, _! J
, V5 ]0 b- ?; Z& l% d首先从http://www.hsqldb.org/下载一个hsqldb的稳定版本,解压后可以浏览解压目录下的index.html,它描述了各个目录所包含内容,在doc段里有一个重要的链接User Guide: index.html,有空好好研究吧!
1 i0 {; S* i! m+ d
- I; h$ F3 y3 k' F1 z/ g" ?数据库实例创建
: n- K! y; M; w" u4 C3 r
在hsqldb的管理中,如果启动的数据库文件不存在,就新建该数据库文件。 ! M: }8 s; m% i; T9 M# C, u' S- ~
# k9 d7 s) k4 L4 t
Hsldb启动 ! J( C( t  l$ C" A4 H% h0 ?; E
Hsqldb的启动模式有三种主要模式,其他参见User Guide:
. o8 p6 O- b2 l- FlServer
2 S' ~- O0 R' w9 f, X! k: Y该模式就像启动mysql、oracle等数据库一样,数据库启动后作为一个服务存在,其他数据库工具可以通过jdbc的方式访问他,这是我们最熟悉的模式。启动脚本如下:
复制内容到剪贴板
代码:
java -cp hsqldb.jar org.hsqldb.Server -database.0 ./db/test -dbname.0 test
后面参数: 6 K, [4 z7 _5 z2 `% [& X. Z2 ^3 }# P
-database.n 数据库文件(其他数据库中对应:数据库实例)地址,支持相对路径,注意使用反斜杠 6 G3 l5 O' E8 G: ?" e
-dbname.n 数据库文件的访问同义词,就是用这个名称访问数据库的 " E$ Y: T+ ?* \! ^; P5 d5 L, E
server模式jdbc访问方式:
复制内容到剪贴板
代码:
Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost:9002/test", "sa", "");
可以启动多个数据库文件,例如:
复制内容到剪贴板
代码:
java -cp hsqldb.jar org.hsqldb.Server -database.0 ./db/test0 -dbname.0 test0  -database.1 ./db/test1 -dbname.1 test1
lIn-Process (Standalone) 9 N6 E5 o, S& X: |
该模式更接近于文件型数据库这个概念,当你访问时他就启动,这种模式访问速度最快,缺点是只能当前访问线程使用,其他数据库工具不能同时访问。例如jdbc访问:
复制内容到剪贴板
代码:
Connection c = DriverManager.getConnection("jdbc:hsqldb:file:/opt/db/testdb", "sa", "");
lIn-Memory 8 T5 z7 U8 w5 ]8 m- M) H: ~4 P
顾名思义,内存中的数据库,你所做的数据库ddl、dml不会写入磁盘,也是当你访问时他就启动。例如jdbc访问:
复制内容到剪贴板
代码:
Connection c = DriverManager.getConnection("jdbc:hsqldb:mem:aname", "sa", "");
Hsqldb 管理工具
; q8 }+ v; D) P1 ihsqldb.jar中自带了一个数据库管理工具:DatabaseManagerSwing(Swing界面,还有一个是Awt界面的:DatabaseManager),该工具可以通过jdbc访问多种数据库。
# u. o$ S+ ]* @: |我们使用server模式启动hsqldb数据库,然后运行下列命令:
复制内容到剪贴板
代码:
java -cp hsqldb.jar org.hsqldb.util.DatabaseManager
就可打开主界面 . C$ `0 D0 W3 [7 a( C
连接时注意选择:Type,应该是HSQL Database Engine Server ; W' C, {  v- c
对于第一次使用可以使用它自带的功能,创建一些测试表,挺好的吧
/ w; R0 ]6 v8 c: @
3 d& O/ n$ O8 @9 R% |Hsldb关闭 9 \- k$ W5 {' ], a. R! G6 ~: s
对于任何一种启动模式,都可以在输入sql脚本的状态输入:SHUTDOWN 或 SHUTDOWN COMPACT 语法来关闭数据库。
" H; w5 X4 t" y6 _( o) l$ L对于In-process和In-memory这两种模式只要所有的连接关闭了,数据库也就关闭了。: X' |/ [* J' I- G; t

4 O- n& d8 j  z# TServer模式参数设置
) B, m* a$ F) H4 z) N# A' ^
在server模式下可以设置一些参数,主要的例如访问端口,可以参见User Guide的第四章高级属性,一般我们可以在启动脚本的目录下编辑一个server.properties,内容如下:
复制内容到剪贴板
代码:
server.port=9002
server.trace=true
Sqltool工具使用 0 h  H% F$ f, A; f/ t: s; C; X
在目录src\org\hsqldb\sample下有一个sqltool.rc文件,将其拷贝到工具使用命令目录中,修改如下片断:
$ u% a$ ]0 D/ G* [. R% K& O4 D. W" }6 C$ q5 C
urlid test
4 ~3 F" Y) }3 V/ g. j7 n4 I9 xurl jdbc:hsqldb:hsql://localhost:9002/test
; U9 Y6 ~6 {- e0 {! N  C4 m( P5 \username sa
# D) m. J$ E" ~! q1 ^password
) u$ O' o% a+ h, ^& S; |: K" Y+ M
& u8 y, H" z5 D* w其中urlid就是启动hsqldb的参数-dbname.0 test 7 ~- G8 M# H- w6 R3 y2 B, t
然后使用如下命令:
复制内容到剪贴板
代码:
java -jar hsqldb.jar --sql "select * from customer" --rcfile sqltool.rc test
大家可以通过“java -jar hsqldb.jar –help”看看其他的参数
在web应用中嵌入hsqldb   l  `: ^, q2 T% ~5 ~/ ?2 M7 B. p
写一个Listener
4 D6 ]" k+ Y0 [; ~3 s5 y4 \将hsqldb嵌入到web应用首要解决的问题是数据库的启动和关闭问题,参考springside项目的方法加入一个容器级的Listener,代码如下:
复制内容到剪贴板
代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
  
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
  
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hsqldb.Server;
  
/**
* 该类的职责是在WebApp启动时自动开启HSQL服务. 依然使用Server方式,不受AppServer的影响.
*
* @author frank
* @author calvin
*/
public class HsqlListener implements ServletContextListener {
    protected Logger logger = Logger.getLogger(getClass());
  
    /*
     * (非 Javadoc)
     *
     * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
     */
    public void contextInitialized(ServletContextEvent sce) {
        logger.info(" ============= HsqlListener initialize...");
  
        // 获得数据库文件访问路径
        String path = getDbPath(sce);
        if (!path.endsWith("/"))
            path = path + "/";
  
        if (StringUtils.isEmpty(path)) {
            logger.info(" ============= Can't get hsqldb.path from web.xml Context Param");
            return;
        }
  
        logger.debug("hsqldb_path:" + path);
  
        // 数据库文件名
        String dbName = sce.getServletContext().getInitParameter("hsql.dbName");
        if (StringUtils.isEmpty(dbName)) {
            logger.info(" ============= Can't get hsqldb.dbName from web.xml Context Param");
            return;
        }
  
        // 数据库访问端口
        int port = -1;
        try {
            port = Integer.parseInt(sce.getServletContext().getInitParameter("hsql.port"));
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
  
        // 启动数据库
        startServer(path, dbName, port);
    }
  
    /**
     * 获得数据库文件访问路径
     *
     * @param sce
     * @return
     */
    private String getDbPath(ServletContextEvent sce) {
        String path = sce.getServletContext().getInitParameter("hsql.dbPath");
  
        if (path.startsWith("{user.home}")) {
            path = path.replaceFirst("\\{user.home\\}", System.getProperty("user.home").replace('\\', '/'));
        }
        if (path.startsWith("{webapp.root}")) {
            path = path.replaceFirst("\\{webapp.root\\}", sce.getServletContext().getRealPath("/").replace('\\', '/'));
        }
  
        return path;
    }
  
    /**
     * 启动数据库
     *
     * @param dbPath
     * @param dbName
     * @param port
     */
    private void startServer(String dbPath, String dbName, int port) {
        Server server = new Server();
  
        server.setDatabaseName(0, dbName);
        server.setDatabasePath(0, dbPath + dbName);
  
        if (port != -1)
            server.setPort(port);
  
        server.setSilent(true);
        server.setTrace(true);
  
        server.start();
  
        logger.info(" ============= hsqldb started...");
        // 等待Server启动
        try {
            Thread.sleep(800);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
  
    /*
     * (非 Javadoc)
     *
     * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
     */
    public void contextDestroyed(ServletContextEvent sce) {
        logger.info(" ============= HsqlListener destroyed...");
  
        Connection conn = null;
        try {
            Class.forName("org.hsqldb.jdbcDriver");
            conn = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost:9002/weed", "sa", "sa");
            Statement stmt = conn.createStatement();
  
            stmt.executeUpdate("SHUTDOWN;");
  
            logger.info(" ============= hsqldb shutdown...");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
增加web.xml配置
5 @* L: j9 ^* v! T- sweb.xml配置增加如下:
复制内容到剪贴板
代码:

<!--HSQLDB Listener的参数,随WebApp启动停止的Listener
        {user.home}        System.getProperty("user.home")
        {webapp.root}      servletContext.getRealPath("/")
    -->
    <context-param>
        <param-name>hsql.dbPath</param-name>
        <param-value>{webapp.root}/WEB-INF/dbms/db</param-value>
    </context-param>
  
    <context-param>
        <param-name>hsql.dbName</param-name>
        <param-value>weed</param-value>
    </context-param>
  
    <context-param>
        <param-name>hsql.port</param-name>
        <param-value>9002</param-value>
</context-param>

<!--
    控制HSQLDB随Web App 启动停止
    -->
    <listener>
        <listener-class>test.HsqlListener</listener-class>
    </listener>
好了,你现在可以像访问mysql、oracle等其他数据库一样配置jdbc连接访问hsqldb了,在HsqlListener中有一个类org.hsqldb.Server,有空你可以研究一下他的源码。

hFQZMtipTFfJcXH

提示: 该帖被管理员或版主屏蔽

Hello DrJohn Hello

Hello my friends :)
;)

Extremely powerful

Accutane is a form of vitamin A. It reduces the amount of oil released by oil glands in your skin, and helps your skin renew itself more quickly
Buy Accutane
Cheap accutane
DrJohn Reccomended ;)

fKhMepIZjoElG

<a href="http://www.bahraichblogs.com/BrendonMiles/12819/">mesothelioma prevention</a>
http://www.bahraichblogs.com/BrendonMiles/12819/
mesothelioma prevention
发新话题
查看积分策略说明

快速回复主题

选项

[完成后可按 Ctrl+Enter 发布] 预览帖子 恢复数据 清空内容