問題
使用h2做內存數據庫時,查詢某表,程序提示table不存在。
引用h2版本
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.196</version>
</dependency>
啟動數據庫
public static void startH2Server() {
try {
System.out.println("正在啟動h2數據庫...");
Server.createTcpServer().start();
System.out.println("h2數據庫啟動成功...");
} catch (SQLException e) {
System.out.println("啟動h2數據庫出錯:" + e.toString());
e.printStackTrace();
throw new RuntimeException(e);
}
}
初始化數據庫
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 = "......";//初始化數據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數據庫數據完成!");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != stmt) {
stmt.close();
}
if (null != conn) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
查詢數據庫
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;
}
但是在使用此查詢時,總是提示查詢的table不存在。
org.h2.jdbc.JdbcSQLException: Table "xxxxxx" not found; SQL statement:.......
明明在初始化數據庫時,使用count方法能查詢到值,怎么單獨查詢,卻又找不到table了呢!
首先懷疑是SQL拼寫錯誤,將查詢SQL,放入“初始化方法”中執行,也可以出查詢結果,說明查詢用的SQL是沒有寫錯。
但是單獨執行時,一直提示找不到table,這就真奇怪了~
解決
在官方網站:http://www.h2database.com/html/features.html#in_memory_databases找到這么一段話,感覺有了新的希望。
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.
大意就是關閉最后一個conn時,就關閉了database。如果要保持database 打開可用,需要的數據庫URL中添加參數:;DB_CLOSE_DELAY=-1。
看來是因為在數據庫初始化的finally中將conn關閉,導致關閉了database。所以再執行單獨的查詢SQL時,因為database已經關閉,所以才會提示找不到table。
將JDBC_URL修改為:
private static final String JDBC_URL = "jdbc:h2:tcp://localhost/mem:gacl;DB_CLOSE_DELAY=-1";
問題解決。