H2内存中创建通过Shell访问的服务器

时间:2018-11-08 01:54:40

标签: java h2 dropwizard

我正在使用dropwizard和H2的DataSourceFactory创建一个用于测试的内存数据库。这就是我所拥有的

private static final String DBNAME = String.format("JDBITest-%d", System.currentTimeMillis());

protected final DataSourceFactory config = new DataSourceFactory();
{
    final String url = String.format("jdbc:h2:mem:%s;", DBNAME) +
                       "MODE=MySQL;" +
                       "TRACE_LEVEL_FILE=3;" +
                       "DB_CLOSE_DELAY=-1;" +
                       "IGNORECASE=TRUE";
    System.out.println("Creating in memory H2 using " + url);

    BootstrapLogging.bootstrap();
    config.setUrl(url);
    config.setUser("sa");
    config.setDriverClass("org.h2.Driver");
    config.setValidationQuery("SELECT 1");
}

@Before
public void setUp() throws Exception {
    Server server = Server.createTcpServer().start(); // (4)
    System.out.println("Server started and connection is open.");
    System.out.println("URL: jdbc:h2:" + server.getURL() + "/mem:" + DBNAME);
}

运行时,我看到

Creating in memory H2 using jdbc:h2:mem:JDBITest-1541641621470;MODE=MySQL;TRACE_LEVEL_FILE=3;DB_CLOSE_DELAY=-1;IGNORECASE=TRUE
Server started and connection is open.
URL: jdbc:h2:tcp://0.0.17.56:9092/mem:JDBITest-1541641621470

为什么使用TCP 0.0.17.56?我无法访问此文件,也无法使用H2.jar访问外壳程序。

1 个答案:

答案 0 :(得分:1)

这里有些错误的事情。

H2 具有不同的连接模式。在您的示例中,您为内存中的连接配置了DataSourceFactory,但是随后在@Before方法中,基于 tcp创建了 H2 的新实例连接。有关连接模式here的更多信息。

因此,现在您的内存和tcp中基本上有 2个H2实例,它们是完全无关的。因此,您可能只需要为测试配置一种连接类型。

如果要连接到JVM外部的 H2数据库(例如,通过浏览器),则需要建立基于tcp的连接。

要能够从浏览器连接到数据库,您还需要运行控制台应用程序。哪个应该在h2.jar之内的命令java -jar h2*.jar中。有关此here的更多信息。

最后,这种和平的代码应该适合您(带有内存连接):

private static final String DBNAME = String.format("JDBITest-%d", System.currentTimeMillis());
private ManagedDataSource dataSource;

@Before
public void setUp() {
    System.out.println("Server started and connection is open.");

    final String url = String.format("jdbc:h2:mem:%s;", DBNAME) +
            "MODE=MySQL;" +
            "TRACE_LEVEL_FILE=3;" +
            "DB_CLOSE_DELAY=-1;" +
            "IGNORECASE=TRUE";
    System.out.println("Creating in memory H2 using " + url);

    DataSourceFactory config = new DataSourceFactory();
    BootstrapLogging.bootstrap();
    config.setUrl(url);
    config.setUser("sa");
    config.setDriverClass("org.h2.Driver");
    config.setValidationQuery("SELECT 1");

    dataSource = config.build(null, "test");
}

@Test
public void test() throws SQLException {
    Connection connection = dataSource.getConnection();

    connection.createStatement().executeUpdate("CREATE TABLE TEST (`id` INT)");
    connection.createStatement().executeUpdate("INSERT INTO TEST (`id`) VALUES (1)");
    ResultSet resultSet1 = connection.createStatement().executeQuery("SELECT * FROM TEST WHERE `id` = 1");
    resultSet1.next();
    resultSet1.getInt(1);

    System.out.println("Found ID: " + resultSet1.getInt(1));
}

出局:

Server started and connection is open.
Creating in memory H2 using jdbc:h2:mem:JDBITest-1541649996267;MODE=MySQL;TRACE_LEVEL_FILE=3;DB_CLOSE_DELAY=-1;IGNORECASE=TRUE
Found ID: 1