让Hsqldb随WebAPP一起启动

   首先说一下hsqldb几个优点
  1. 轻巧,只有600多K,运行速度非常快。结合Hibernate数据库无关的特性,非常适合在项目开发的时候使用。
  2. 作为单元测试数据库。单元测试的时候,启动HSQLDB的file模式,数据不存盘,可以保证测试原子性。
  3. 来回复制,随身携带。
  4. 不需要安装,使用非常方便。
  5. 稳定,而且支持的数据量足够大。
  6. 小型项目作为现场数据库使用,不需要安装Oracle之类的大型DB,减轻了维护成本,并且,HSQLDB非常容易备份。

        Hsqldb的各种好处就不再多说了,今天我们谈谈如何让它在我们日常开发中给我们带来更多的便捷。就像标题所说的,让Hsqldb随WebAPP一起启动。比平时用的DB2、Oracle、SQLServer... ...都要简洁方便许多,更重要从开发角度考虑Hsqldb的性能已经足够了。springside也是这么做的。

       废话不多说了,现在开始:

       我们借助Listener来实现此功能。

       先给出一段该Listener的配置信息吧,*^_^*是存在web.xml里的。

xml 代码
  1. <context-param>  
  2.       <param-name>hsql.dbPath</param-name>  
  3.       <param-value>D:/db</param-value>  
  4.   </context-param>  
  5.   
  6.   <context-param>  
  7.      <param-name>hsql.dbName</param-name>  
  8.      <param-value>mydb</param-value>  
  9.   </context-param>  
  10.   
  11.   <context-param>  
  12.       <param-name>hsql.port</param-name>  
  13.       <param-value>9002</param-value>  
  14.   </context-param>  
  15.     
  16.   <listener>  
  17.      <listener-class>  
  18.          systop.com.systopbase.common.HsqlStartListener   
  19.      </listener-class>  
  20.   </listener>  
简单解释一下:
  • hsql.dbPath: 采用绝对路径,且是固定的[D:/db]。而在实际应用中在这里我们更需要的是变量[或者说是相对路径],嘻嘻*^_^*不要着急,写这篇文章是为了让大家了解一下。在我们的systop-base项目中就采用了相对路径的方法,在那里你会有惊喜发现。
  • hsql.dbName:需要说明的是在D:/db目录下确认有mydb.script和mydb.properties两个文件.
  • hsql.port:设置hsqldb的端口,默认是9001,防止冲出使用9002。

接下来我们看看Listener是如何实现的:

java 代码


package systop.com.systopbase.common;   

  

import org.hsqldb.Server;   

import org.springframework.util.FileCopyUtils;   

  

import javax.servlet.ServletContextEvent;   

import javax.servlet.ServletContextListener;   

import java.io.File;   

import java.io.FileOutputStream;   

import java.io.IOException;   

import java.sql.Connection;   

import java.sql.DriverManager;   

import java.sql.Statement;   

  

 /**  

 * 该类的职责是在WebApp启动时自动开启HSQL服务. 依然使用Server方式,不受AppServer的影响. 

 */  

public class HsqlListener implements ServletContextListener {   

  

   /**  

   * Listener 初始化方法.  

   */  

  

  public void contextInitialized(ServletContextEvent sce) {   

  

    String dbName = sce.getServletContext().getInitParameter("hsql.dbName");   

    String path = sce.getServletContext().getInitParameter("hsql.dbPath");   

    int port = -1;   

  

    try {   

      port = Integer.parseInt(sce.getServletContext().getInitParameter("hsql.port"));   

    }catch(Exception e){   

      port = 9001;   

    }   

  

    if (dbName == null || dbName.equals("")){   

     System.out.println("Cant' get hsqldb.dbName from web.xml Context Param");   

     return;   

    }   

     

    File dbDir = new File(path);   

  

    if (!dbDir.exists()) {//判断目录是否存在  

      if (!dbDir.mkdirs()) {//如果不存在创建,如果创建失败直接返回  

        System.out.println("Can not create DB Dir for Hsql:" + dbDir);   

        return;   

      }   

    }   

//以下代码是做数据库恢复的。我们把原始的数据库放在classpath下,当启动web的时候,检查目标  

//数据库是否存在,如果不存在,就把原始数据库复制为指定的数据库   

  

    if (!path.endsWith("/")){   

     path = path + "/";   

    }   

  

    File scriptFile = new File(path + dbName + ".script");   

    File propertiesFile = new File(path + dbName + ".properties");   

  

    if (scriptFile.exists() && propertiesFile.exists()){//判断数据文件是否存在  

      this.startServer(path, dbName, port);   

    } else{   

      System.out.println("Connect failed:Connect Hsqldb error or database files not exits!");   

    }   

  }   

  

  

  /**  

   * 启动Hsqldb服务的方法。  

   * @param dbPath 数据库路径  

   * @param dbName 数据库名称  

   * @param port 所使用的端口号  

   */  

  private void startServer(String dbPath, String dbName, int port) {   

  

    Server server = new Server();//它可是hsqldb.jar里面的类啊。  

  

    server.setDatabaseName(0, dbName);   

    server.setDatabasePath(0, dbPath + dbName);   

  

     if (port != -1){   

      server.setPort(port);   

    }   

  

          server.setSilent(true);   

    server.start();   

    System.out.println("hsqldb started...");   

    // 等待Server启动   

    

    try {   

      Thread.sleep(800);   

    } catch (InterruptedException e){   

      // do nothing   

    }   

  }   

  

    /**  

   * Listener销毁方法,在Web应用终止的时候执行"shutdown"命令关闭数据库. 

   */  

   public void contextDestroyed(ServletContextEvent arg0) {   

    //这里就不用说了,自然是关闭数据库操作   

    Connection conn = null;   

    try {   

      Class.forName("org.hsqldb.jdbcDriver");   

      conn = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost:9002/bookstore", "sa", "");   

      Statement stmt = conn.createStatement();   

      stmt.executeUpdate("SHUTDOWN;");   

    } catch (Exception e){   

      // do nothing   

   }   

  }   

}  

现在就部署到Web应用中去尝试一下吧。:)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值