h2錯(cuò)誤提示:Table not found

問(wèn)題

使用h2做內(nèi)存數(shù)據(jù)庫(kù)時(shí),查詢某表,程序提示table不存在。

引用h2版本

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.196</version>
</dependency>

啟動(dòng)數(shù)據(jù)庫(kù)

public static void startH2Server() {
    try {
        System.out.println("正在啟動(dòng)h2數(shù)據(jù)庫(kù)...");
        Server.createTcpServer().start();
        System.out.println("h2數(shù)據(jù)庫(kù)啟動(dòng)成功...");
    } catch (SQLException e) {
        System.out.println("啟動(dòng)h2數(shù)據(jù)庫(kù)出錯(cuò):" + e.toString());
        e.printStackTrace();
        throw new RuntimeException(e);
    }
}

初始化數(shù)據(jù)庫(kù)

private static final String JDBC_URL = "jdbc:h2:tcp://localhost/mem:gacl";
private static final String USER = "gacl";//用戶名
private static final String PASSWORD = "123";//密碼

public static void initTables() {
    Connection conn = null;
    Statement stmt = null;
    try {
        String sql = "......";//初始化數(shù)據(jù)SQL
        Class.forName(DRIVER_CLASS);
        conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD);
        stmt = conn.createStatement();
        stmt.execute(sql);
        sql = "SELECT COUNT(1) FROM xxxxxx";
        rs = stmt.executeQuery(sql);
        while (rs.next()) {
            System.out.println("ccby_ts_attributevo count:{}", rs.getInt(1));
        }
        System.out.println("初始化H2數(shù)據(jù)庫(kù)數(shù)據(jù)完成!");
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (null != stmt) {
                stmt.close();
            }
            if (null != conn) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

查詢數(shù)據(jù)庫(kù)

public static List<Object> query(Map<String, String> params) {
    Connection conn = null;
    Statement stmt = null;
    List<Object> list = new ArrayList<Object>();
    try {
        Class.forName(DRIVER_CLASS);
        conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD);
        stmt = conn.createStatement();
        String sql = "SELECT ......";//查詢SQL
        ResultSet rs = stmt.executeQuery(sql);
        while (rs.next()) {
            //處理rs
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (null != stmt) {
                stmt.close();
            }
            if (null != conn) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    return list;
}

但是在使用此查詢時(shí),總是提示查詢的table不存在。

org.h2.jdbc.JdbcSQLException: Table "xxxxxx" not found; SQL statement:.......

明明在初始化數(shù)據(jù)庫(kù)時(shí),使用count方法能查詢到值,怎么單獨(dú)查詢,卻又找不到table了呢!

首先懷疑是SQL拼寫錯(cuò)誤,將查詢SQL,放入“初始化方法”中執(zhí)行,也可以出查詢結(jié)果,說(shuō)明查詢用的SQL是沒(méi)有寫錯(cuò)。

但是單獨(dú)執(zhí)行時(shí),一直提示找不到table,這就真奇怪了~

解決

在官方網(wǎng)站:http://www.h2database.com/html/features.html#in_memory_databases找到這么一段話,感覺(jué)有了新的希望。

By default, closing the last connection to a database closes the database. 
For an in-memory database, this means the content is lost. 
To keep the database open, add ;DB_CLOSE_DELAY=-1 to the database URL. 
To keep the content of an in-memory database as long as the virtual machine is alive,
use jdbc:h2:mem:test;DB_CLOSE_DELAY=-1.

大意就是關(guān)閉最后一個(gè)conn時(shí),就關(guān)閉了database。如果要保持database 打開(kāi)可用,需要的數(shù)據(jù)庫(kù)URL中添加參數(shù):;DB_CLOSE_DELAY=-1。

看來(lái)是因?yàn)樵跀?shù)據(jù)庫(kù)初始化的finally中將conn關(guān)閉,導(dǎo)致關(guān)閉了database。所以再執(zhí)行單獨(dú)的查詢SQL時(shí),因?yàn)閐atabase已經(jīng)關(guān)閉,所以才會(huì)提示找不到table。

將JDBC_URL修改為:

private static final String JDBC_URL = "jdbc:h2:tcp://localhost/mem:gacl;DB_CLOSE_DELAY=-1";

問(wèn)題解決。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容