让Hsqldb随WebAPP一起启动

翻译|其它|编辑:郝浩|2007-10-18 11:02:55.000|阅读 1424 次

概述:

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

      首先说一下  hsqldb  几个优点

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

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

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

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

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

xml 代码
<context-param>  
      <param-name>hsql.dbPath</param-name>  
      <param-value>D:/db</param-value>  
  </context-param>  
  
  <context-param>  
     <param-name>hsql.dbName</param-name>  
     <param-value>mydb</param-value>  
  </context-param>  
  
  <context-param>  
      <param-name>hsql.port</param-name>  
      <param-value>9002</param-value>  
  </context-param>  
    
  <listener>  
     <listener-class>  
         systop.com.systopbase.common.HsqlStartListener   
     </listener-class>  
  </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   
    }   
  }   


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:JavaEyE

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP