如何在创建新数据库之前检查现有的 h2 数据库

How to check existing h2 database before creating a new one

我正在使用 java servlet 和 h2 嵌入式数据库开发学生数据库 Web 应用程序。我需要知道如何找到典型的学生数据库是否存在。因此,如果它不存在,则必须创建它,否则程序应继续使用现有程序。

tl;博士

IFEXISTS=TRUE 添加到您的连接 URL 字符串。

H2 创建数据库,如果不存在

您问的是:

I need to know how to find whether the typical student database exists or not. so that, if it is not there, it must be created or else the program should continue with the existing one.

默认情况下,H2 会自动创建数据库(如果尚不存在)。所以你的那部分问题没有意义。

指定文件位置作为建立 DataSource object 的一部分。这里我们使用org.h2.jdbcx.JdbcDataSource as our implementation of javax.sql.DataSource.

private javax.sql.DataSource establishDataSource() {
    org.h2.jdbcx.JdbcDataSource ds = Objects.requireNonNull( new JdbcDataSource() );  // Implementation of `DataSource` bundled with H2. You may choose to use some other implementation. 
    ds.setURL( "jdbc:h2:/path/to/MyDatabase;" );
    ds.setUser( "scott" );
    ds.setPassword( "tiger" );
    ds.setDescription( "An example database." );
    return ds ;
}

实例化一个DataSourceobject。随身携带,以便在需要访问数据库时使用。

DataSource dataSource = this.establishDataSource();
…

DataSource object 不会导致任何事情发生。 DataSource object 仅包含定位和连接到特定数据库所需的信息片段。

尝试连接到数据库。这是事情开始发生的时候。

try(
    Connection conn = dataSource.getConnection() ;
)
{ … }

第一次调用 DataSource#getConnection 导致 H2:

  1. 在文件系统中的指定位置建立一个新的数据库文件(如果尚不存在)。
  2. 打开数据库连接。

但要回答您的问题标题,请继续阅读。

IFEXISTS

您可以在连接尝试中指定仅当请求的数据库已经存在时才能完成连接。此功能使用 IFEXISTS=TRUE 语法。

String url = "jdbc:h2:/path/to/MyDatabase;IFEXISTS=TRUE";

这导致 H2:

  • 在给定位置查找现有数据库。
    • 如果不存在数据库,则抛出异常。
    • 如果找到现有数据库,打开一个连接。

Trap 数据库不存在时抛出的异常

文件

您检查文件系统中是否存在数据库文件,假设您的数据库持久存储(而不是 in-memory database)。

我发现这个方法解决了我的问题,首先连接对象检查数据库是否存在,如果不存在,它会在创建数据库的地方抛出异常。

try
{
Connection c=DriverManager.getConnection("jdbc:h2:aaa;IFEXISTS=TRUE",username,password);
}
Catch(final Exception e)
{
connection c=DriverManager.getConnection("jdbc:h2:aaa","user","pass");
}
package com.dora.databasecheck;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;

@Configuration
public class DataSourceInit {

    boolean dbExists = false;

    @Bean(name = "dataSource")
    public DataSource getDataSource(){
        DataSource dataSource = createDataSource();
        DatabasePopulatorUtils.execute(createDatabasePopulator(), dataSource);
        return dataSource;
    }

    private DatabasePopulator createDatabasePopulator() {
        ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
        databasePopulator.setContinueOnError(true);
        if(!dbExists){
            databasePopulator.addScript(new ClassPathResource("db/sql/create-db.sql"));
            databasePopulator.addScript(new ClassPathResource("db/sql/insert-data.sql"));
        }
        return databasePopulator;
    }

    private SimpleDriverDataSource createDataSource() {
         SimpleDriverDataSource simpleDriverDataSource = new SimpleDriverDataSource();
         simpleDriverDataSource.setDriverClass(org.h2.Driver.class);
         simpleDriverDataSource.setUsername("sa");
         simpleDriverDataSource.setPassword("");
         Connection conn = null;
        try{
            conn = DriverManager.getConnection("jdbc:h2:~/doradb;IFEXISTS=TRUE","sa","");           
            this.dbExists =true;

         }
        catch(Exception e){         
             this.dbExists = false;  
        }

         simpleDriverDataSource.setUrl("jdbc:h2:~/doradb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");

        return simpleDriverDataSource;      
    }
}