让Hsqldb随WebAPP一起启动

来源:互联网 发布:软件源代码提取 编辑:程序博客网 时间:2024/06/08 08:16
   首先说一下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应用中去尝试一下吧。:)

原创粉丝点击