将H2数据库嵌入WEB-INF目录中 [英] Embedding an H2 Database within the WEB-INF Directory

查看:652
本文介绍了将H2数据库嵌入WEB-INF目录中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个嵌入式H2数据库,我想将其放置在Web应用程序的WEB-INF目录中.

I have an embedded H2 Database I'd like to put in the WEB-INF directory of a web application.

在JDBC网址中引用此内容的正确方法是什么?

What is the proper way to refer to this in a JDBC url?

理想情况下,我想要一个既适用于WAR,又适用于扩展的WAR(如果可能)的解决方案.

Ideally I'd like a solution that would work both for a WAR, and an expanded WAR (If possible).

谢谢您的帮助!

仅供参考,我尝试了以下操作:

FYI, I've tried the following:

jdbc:h2:/WEB-INF/data/myDB;CIPHER=AES

但这会导致:

org.h2.jdbc.JdbcSQLException: A file path that is implicitly relative to the current working directory is not allowed in the database URL "jdbc:h2:/WEB-INF/data/myDB;CIPHER=AES". Use an absolute path, ~/name, ./name, or the baseDir setting instead. [90011-187]

将其更改为: jdbc:h2:./WEB-INF/data/myDB; CIPHER = AES

Changing this to: jdbc:h2:./WEB-INF/data/myDB;CIPHER=AES

导致以下错误,这清楚地表明了它试图将我的数据库放置在Tomcat的bin目录中,而不是我想要的真实WEB-INF目录中的情况:

Results in the following error, which clearly shows its trying to put my database in Tomcat's bin directory, rather than the true WEB-INF directory where I want it:

org.h2.jdbc.JdbcSQLException: Error while creating file "C:/Program Files/Apache Software Foundation/Tomcat 7.0/bin/WEB-INF" [90062-187]

推荐答案

我设法使嵌入式解决方案在没有AES的情况下工作,如下所示:

I managed to make the embedded solution work without AES like this:

try {
    Class.forName("org.h2.Driver");
    Connection conn = DriverManager.getConnection(
        "jdbc:h2:" + getServletContext().getRealPath("/") + 
        "/WEB-INF/data/myDB", "sa", "");
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("SELECT * FROM INFORMATION_SCHEMA.TABLES");
    while (rs.next()) {
    }
    rs.close();
    stmt.close();
    conn.close();
} catch(SQLException e) {
} catch(ClassNotFoundException e) {
} finally {
}

这已在Tomcat8上使用H2 1.3.176进行了测试.只要嵌入式数据库已经在war文件中,它就可以与H2 1.4和CIPHER=AES一起使用.

This was tested with H2 1.3.176 on Tomcat8. It should work with H2 1.4 and CIPHER=AES provided the embedded database is already inside the war file I guess.

这个想法是这样的:您需要获取绝对路径,并且根据您部署war文件的方式,部署路径可能会有所不同.

The idea is the following: you need to get the absolute path, and that deployment path may not be the same depending on how you deployed the war file.

因此,我们需要使用servlet上下文并请求真实路径.为此,我们使用getServletContext().getRealPath("/")并根据您的需要在其后附加/WEB-INF/data/myDB.

So we need to use the servlet context and request the real path. For this we use getServletContext().getRealPath("/") and append /WEB-INF/data/myDB to it as per your needs.

我从未测试过CIPHER=AES部分,因为我从未使用过它.

I did not test the CIPHER=AES part as I've never used it.

更新:

要获得对Servlet上下文的良好引用非常棘手.可以使用原始请求,获取基础会话,然后到达servlet上下文.

Getting a good reference to the servlet context is tricky. One could use a raw request, get the underlying session and then get to the servlet context.

但是最好在Tomcat中部署/启动应用程序后立即打开嵌入式H2数据库,并在应用程序停止后立即正确关闭嵌入式H2数据库.

But it would be good to have the embedded H2 database opened as soon as the application is deployed/started in Tomcat, and closed properly as soon as the application is stopped.

为了执行该操作,需要使用侦听器.这是我对以前答案的更新建议.这次,该解决方案已使用AES CIPHER完善,应该可以轻松插入您的代码中.

In order to perform that, the use of a listener is needed. Here's what I propose as an update to my previous answer. This time the solution is complete with AES CIPHER and it should be easy to plug into your code.

建议:侦听器Java代码也可以轻松修改以启动H2 tcp服务器,这对于启用自动混合模式(嵌入式+ tcp)很有用.

Suggestion: the listener java code can be easily modified to start a H2 tcp server as well, useful to enable the automatic mixed mode (embedded+tcp).

在文件web.xml中添加3行:

Add 3 lines to the file web.xml:

<listener>
  <listener-class>com.mine.MyServletContextListener</listener-class>
</listener>

文件MyServletContextListener.java:

File MyServletContextListener.java:

package com.mine;

import javax.servlet.*;
import java.sql.*;

public class MyServletContextListener implements ServletContextListener {
  Connection conn;

  public void contextInitialized(ServletContextEvent sce) {

    try {
      Class.forName("org.h2.Driver");
      conn = DriverManager.getConnection( "jdbc:h2:" + sce.getServletContext().getRealPath("/") + "/WEB-INF/data/myDB;CIPHER=AES", "sa", "aespassword dbpassword");
      Statement stmt = conn.createStatement();
      ResultSet rs = stmt.executeQuery("SELECT * FROM INFORMATION_SCHEMA.TABLES");
      while (rs.next()) {
      }
      rs.close();
      stmt.close();
    } catch(SQLException e) {
    } catch(ClassNotFoundException e) {
    } finally {
    }

  }

  public void contextDestroyed(ServletContextEvent sce) {

    try {
      conn.close();
    } catch(SQLException e) {
    } finally {
    }

  }

}

这篇关于将H2数据库嵌入WEB-INF目录中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆