【问题标题】:How to check existing h2 database before creating a new one如何在创建新数据库之前检查现有的 h2 数据库
【发布时间】:2017-01-10 16:55:32
【问题描述】:

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

【问题讨论】:

  • 你的软件栈是什么,Spring,Hibernate?
  • antoniogoncalves.org/2014/12/11/…应该有更新选项。
  • 亲爱的投票者:请在投票的同时留下批评。对我来说,这似乎是一个明智而重要的问题。
  • 欢迎来到 Stack Overflow。你可以改进你的问题。请阅读How to Ask,包括“如何以聪明的方式提问”链接。

标签: java servlets jdbc h2


【解决方案1】:

tl;博士

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

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

你问:

我需要知道如何查找典型的学生数据库是否存在。因此,如果它不存在,则必须创建它,否则程序应该继续现有的。

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

指定文件位置作为建立DataSource 对象的一部分。这里我们使用org.h2.jdbcx.JdbcDataSource作为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 ;
}

实例化一个DataSource 对象。保留它以供需要访问数据库时使用。

DataSource dataSource = this.establishDataSource();
…

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

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

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

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

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

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

IFEXISTS

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

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

这会导致 H2:

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

捕获数据库不存在时抛出的异常。

文件

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

【讨论】:

    【解决方案2】:
    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;      
        }
    }
    

    【讨论】:

      【解决方案3】:

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

      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");
      }
      

      【讨论】:

      • 是的@BasilBourque 我根据您的回答推断出这种方法,非常感谢您的信息
      猜你喜欢
      • 1970-01-01
      • 2014-08-13
      • 2019-12-05
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      • 1970-01-01
      • 2011-01-14
      • 2013-01-31
      相关资源
      最近更新 更多