`
阅读更多
以前一直用mysql做测试数据库,多人协作起来每个人都要安装配置数据库,数据源,还得防着不能把自己的jdbc.properties传上去把别人搞晕掉,现在改成轻便的嵌入式数据库hsqldb,麻烦事少了很多。使用hsqldb作为测试数据库,涉及到两个问题,一个是Web应用启动关闭的时候要同时启动和关闭hsqldb server,另外一个就是在执行单元测试的时候也要启动和关闭hsqldb server.

hsqldb有几种启动方式,其中有res,mem等方式数据库结构都是只读的,hibernate hbm2ddl会报The database is in read only mode in statement [create]。所以最终还是决定使用独立的server模式。但是需要自己控制启动和关闭。

1.让Hsqldb随Web应用启动和关闭

这个实际上就是一个listener。代码如下:

<!---->/**
 * 该类的职责是在WebApp启动时自动开启HSQL服务.
 * 依然使用Server方式,不受AppServer的影响.
 *
 * 
@author frank
 * 
@author calvin
 
*/
public class HsqlListener implements ServletContextListener {
    
protected static Log logger = LogFactory.getLog(HsqlListener.class);

    
private final static String DEFAULT_DB_PATH = "{user.home}/springside/db";

    
public void contextInitialized(ServletContextEvent sce) {
        logger.info(
"HsqlListener initialize");

        String dbName 
= Config.getString("metawork.hsql.dbName");

        
int port = -1;
        
try {
            port 
= Integer.parseInt(Config.getString("metawork.hsql.port"));
        }
        
catch (Exception e) {
        }

        
if (StringUtils.isEmpty(dbName)) {
            logger.error(
"Cant' get hsqldb.dbName from web.xml Context Param");
            
return;
        }

        String path 
= null;
        
try {
            path 
= getDbPath(sce);
        } 
catch (URISyntaxException e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }

        File dbDir 
= new File(path);
        
if (!dbDir.exists()) {
            logger.info(
"Create Path:" + path);
            
if (!dbDir.mkdirs()) {
                logger.error(
"Can not create DB Dir for Hsql:" + dbDir);
                
return;
            }
        }

        
if (!path.endsWith("/"))
            path 
= path + "/";

        startServer(path, dbName, port);
    }

    
private String getDbPath(ServletContextEvent sce) throws URISyntaxException {
        String path 
= Config.getString("metawork.hsql.dbPath");

        
if (StringUtils.isEmpty(path)) {
            path 
= DEFAULT_DB_PATH;
        }
        
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('\\''/'));
        }
        
if (path.startsWith("{classpath}")) {
            path 
= path.replaceFirst("\\{classpath\\}"this.getClass().getClassLoader().getResource("").toURI().toString().replace("file:/"""));   
        }
        
return path;
    }

    
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.start();
        logger.info(
"hsqldb started");
        
// 等待Server启动
        try {
            Thread.sleep(
800);
        }
        
catch (InterruptedException e) {
            
// do nothing
        }
    }

    
public void contextDestroyed(ServletContextEvent sce) {
        String dbName 
= Config.getString("metawork.hsql.dbName");
        Connection conn 
= null;
        
try {
            Class.forName(
"org.hsqldb.jdbcDriver");
            conn 
= DriverManager.getConnection("jdbc:hsqldb:hsql://localhost:" + Config.getString("metawork.hsql.port"+ "/" + dbName,
                    
"sa""");
            Statement stmt 
= conn.createStatement();
            stmt.executeUpdate(
"SHUTDOWN;");
        } 
catch (Exception e) {
            
//do nothing
        }

    }
}

这个类修改自SpringSide1.0M3里面的相应类,把从ServletContext中获取参数的过程全部替换成了Config.getString(),这个Config是静态导入的一个Configuration对象,使用了Apache commons Configuration,读取的配置文件如下:

<!---->metawork.hsql.dbPath={classpath}hsqldb
metawork.hsql.dbName
=mwdb
metawork.hsql.port
=9002

其中指定了数据库文件位置、数据库名称、服务端口。使用种方式来配置启动hsqldb,主要是为了后面的单元测试的情况能够和这里使用相同的一套配置。注意我把数据库文件放在了${app.home}/WEB-INF/classes/hsqldb/目录。

如上配置,在系统的jdbc.properties里面就可以这样写了:

<!---->
jdbc.driverClassName
=org.hsqldb.jdbcDriver
jdbc.url
=jdbc:hsqldb:hsql://localhost:9002/mwdb
jdbc.username
=sa
jdbc.password
=


2.单元测试

上面的HsqlListener控制了在web应用启动的时候启动hsqldb,web应用停止的时候停止hsqldb,但是我们在做单元测试的时候,是没有启动Web应用的,于是就有可能导致无法连接到数据库。解决的方法是在单元测试运行开始之前,启动数据库。写单元测试基类如下:

<!---->@ContextConfiguration
public class BaseDaoTestCase extends AbstractTransactionalDataSourceSpringContextTests{

    
private static final Logger logger = Logger.getLogger(BaseDaoTestCase.class);
    
    
static {
        logger.info(
"Start up hsqldb");
        
        String dbName 
= Config.getString("metawork.hsql.dbName");

        
int port = -1;

        port 
= Integer.parseInt(Config.getString("metawork.hsql.port"));

        
        String path 
= null;
        
        path 
= getDbPath();
        
        File dbDir 
= new File(path);
        
if (!dbDir.exists()) {
            dbDir.mkdirs();
        }

        
if (!path.endsWith("/"))
            path 
= path + "/";

        startServer(path, dbName, port);
        
        logger.info(
"Hsqldb started successfully.");
    }
    
    @Override
    
protected String[] getConfigLocations() {
        
return new String[] { "classpath*:/context/*.xml" };
    }
    
    
public void testX(){
        
    }
    
   
private static String getDbPath(){
        String path 
= Config.getString("metawork.hsql.dbPath");

        
if (path.startsWith("{classpath}")) {
            
try {
                path 
= path.replaceFirst("\\{classpath\\}", BaseDaoTestCase.class.getClassLoader().getResource("").toURI().toString().replace("file:/"""));
            } 
catch (URISyntaxException e) {
                
// TODO Auto-generated catch block
                e.printStackTrace();
            }   
        }
        
        
return path;
    }
   
   
private static 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.start();
       
       
// 等待Server启动
       try {
           Thread.sleep(
800);
       }
       
catch (InterruptedException e) {
           
// do nothing
       }
   }
   
   @Override
   
public void onTearDown(){
       logger.info(
"Shutdown hsqldb");
       String dbName 
= Config.getString("metawork.hsql.dbName");
       Connection conn 
= null;
       
try {
           Class.forName(
"org.hsqldb.jdbcDriver");
           conn 
= DriverManager.getConnection("jdbc:hsqldb:hsql://localhost:" + Config.getString("metawork.hsql.port"+ "/" + dbName,
                   
"sa""");
           Statement stmt 
= conn.createStatement();
           stmt.executeUpdate(
"SHUTDOWN;");
       } 
catch (Exception e) {
           
//do nothing
       }
       
       logger.info(
"Shutdown hsqldb successfully.");
   }
}

上面的测试基类里面用静态初始化快初始化启动了hsqldb,并最后在onTearDown的时候关闭数据库。这个测试基类继承了Spring的测试类AbstractTransactionalDataSourceSpringContextTests,如果你使用原始的junit TestCase,那么直接在tearDown方法中关闭数据库就好了。

3.数据库图形化访问

用惯了mysql的mysql query browser,总是想着看数据库里面的内容,怎么办呢。你的系统启动起来以后,在shell里面执行如下命令:

<!---->"%JAVA_HOME%/bin/javaw" -classpath ../webapp/WEB-INF/lib/hsqldb-1.8.0.7.jar org.hsqldb.util.DatabaseManager

要注意把其中的hsqldb-xxx.jar的地址改成你自己的地址。启动之后按照你配置的数据库端口,名称等等去连接就可以了。
分享到:
评论

相关推荐

    HSQL数据库下载

    HSQL数据库,全称为HyperSQL Database,是一款轻量级、高性能、完全开源的Java数据库管理系统。它被设计为一个嵌入式数据库,适用于各种应用程序,同时也支持客户端/服务器模式,可以作为独立的数据库服务器使用。...

    HSQL数据库2.2.5

    1. 内存模式:HSQLDB能在内存中创建数据库,这使得它非常适合用于快速原型开发和测试环境,无需进行繁琐的磁盘I/O操作,数据处理速度极快。 2. 单机模式:在单机模式下,HSQLDB可以作为单用户或多个用户同时访问的...

    HSQL安装部署使用手册

    如果你需要在Web应用中使用HSQL,可以将数据库文件复制到Web应用的`WEB-INF`目录下,并将`hsqldb.jar`添加到`WEB-INF/lib`目录,确保Web服务器能够访问到。 ### 七、配置数据源 在你的`applicationcontext.xml`...

    收集的全部HSQL DataBase资料(HSQL DataBase-关于Java 的纯数据库)

    1. **连接数据库**: 使用JDBC(Java Database Connectivity)接口建立与HSQL数据库的连接。通过`Class.forName()`加载驱动,然后使用`DriverManager.getConnection()`创建连接。 2. **创建表**: 通过SQL语句创建表,...

    有关hsql处理文本数据库的笔记

    在IT行业中,文本数据库是一种非常实用的数据存储方式,特别是在处理大量非结构化数据时。HSQL(HyperSQL)是一个开源的关系型数据库管理系统,它支持内存模式、文件模式以及服务器模式,能够处理各种类型的数据,...

    Hsqldb-java-connection:在Java编程中使用Hsql(内存数据库)数据库

    例如,使用JUnit进行测试时,可以使用如下方式在测试开始时创建数据库,测试结束后清除数据: ```java @ClassRule public static TestRule dbRule = new DatabaseRule(new HsqlDatabase()); @Test public void ...

    Oracle数据库移植到HsqlDB操作手册.docx

    3. **在Web工程中使用HsqlDB**: - **依赖库**:在Web应用的类路径中添加HsqlDB的JAR文件,确保能正确识别和连接数据库。 - **配置更改**:修改Spring等框架的数据库连接配置,包括URL、用户名、密码等,指向新的...

    hsql数据转移mysql

    本话题聚焦于将HSQL数据库的数据迁移到MySQL的过程,这是一个常见的需求,特别是在开发、测试和生产环境之间进行数据同步时。以下是对这一过程的详细说明: 1. **HSQL数据库**:HSQLDB(HyperSQL Database)是一款...

    jira从HSQL迁移到MYSQL的方法

    1. **导出XML文件**:使用Jira的内置工具导出当前HSQL数据库中的所有数据到一个XML文件。这一步骤是通过Jira管理界面完成的,具体步骤根据版本的不同可能会有所差异。 #### 三、准备MySQL环境 1. **创建数据库**:...

    HSQL源代码

    这两个库在Eclipse项目中是必不可少的,因为HSQLDB的开发和测试过程会用到它们。 "eclise下建立工程.txt"文件很可能是Eclipse工程配置的步骤指南。通常,这会包含如何导入库、设置源代码路径、构建路径、以及运行...

    数据库 jdbc 驱动大全(oracle,sqlserver,sqlserver2005,mysql,hsql) 下载

    本文将详细介绍这些驱动以及如何在不同数据库中使用它们。 首先,Oracle JDBC驱动是Oracle数据库的官方驱动,它分为thin和thick两种类型。Thin驱动是一个纯Java实现,无需Oracle客户端软件,而Thick驱动则需要...

    数据库持久层的UT测试

    这可以通过事务管理实现,例如在JUnit测试类中使用`@Transactional`注解,测试完成后自动回滚事务。 在编写测试用例时,需要注意以下几点: 1. 使用断言(Assert)来验证方法的返回值是否符合预期。 2. 对于异常...

    java开发操作数据库架包

    对于ORM框架如Hibernate或MyBatis,需要在配置文件中指定HSQL的数据源信息,以便框架能够正确地连接和操作数据库。 在进行数据库操作时,需要注意的一些关键点包括:事务管理、性能优化(如批处理、缓存使用)、...

    hsql及其官方说明书

    HSQldb 可以与各种Java应用程序框架如Spring、Hibernate等无缝集成,方便地在应用中使用数据库。 ### 官方手册 《hsqldb_guide.pdf》应该是HSQldb的官方用户指南,包含了详细的使用说明和API参考,是学习和使用...

    HSQL JDBC操作

    JDBC是Java语言中用来规范客户端程序如何访问数据库的应用程序编程接口,它提供了诸如查询和更新数据库中数据的方法。 在描述中提到的“NULL”,在数据库术语中,通常表示未知或无值的数据。在处理数据库时,NULL值...

    用maven构建SpringMVC+JPA+Hibernate+Hsql+jetty的web项目

    在测试阶段,可以利用Jetty启动Web应用,Hsql会在内存中运行数据库,整个流程将非常快捷。如果需要持久化数据,可以将Hsql配置为磁盘模式。 总的来说,这个项目展示了如何利用现代Java Web开发技术搭建一个完整的、...

    hqldb数据库在java程序中以内存方式启动

    通过以上知识点,我们可以理解如何在Java项目中利用HSQLDB进行内存数据库的搭建和使用,以及其在开发和测试中的优势。标签"源码"和"工具"提示了HSQLDB在开发过程中的角色,它既可以作为代码的一部分来操作,也可以...

    spring-batch-database-to-database:Spring Batch 示例,展示了如何在 Spring Batch 的 HSQL 内存中进行读写

    4. **持久化元数据**:Spring Batch 将作业状态和执行信息存储在数据库中,方便监控和重新启动作业。 5. **分片和并行处理**:支持将大型任务拆分为小块并行处理,提高处理速度。 6. **丰富的I/O支持**:Spring ...

    mytest.zip

    为了练习开窗函数,我们首先需要将这些数据导入到HSQL数据库中。可以使用HSQL的命令行工具或者编程接口(如Java)来创建表并加载数据。例如: ```sql CREATE TABLE mytest (column1 datatype, column2 datatype, .....

Global site tag (gtag.js) - Google Analytics