内存模式下的H2数据库无法被Console访问
Posted
技术标签:
【中文标题】内存模式下的H2数据库无法被Console访问【英文标题】:H2 database in memory mode cannot be accessed by Console 【发布时间】:2011-07-01 22:41:26 【问题描述】:我在 servlet 上下文启动时通过以下代码在 H2 数据库中创建内存数据库
void initDb()
try
webserver = Server.createWebServer().start();
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection("jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1","SA","");
InputStream in = getClass().getResourceAsStream("script.sql");
if (in == null)
System.out.println("Please add the file script.sql to the classpath, package " + getClass().getPackage().getName());
else
RunScript.execute(conn, new InputStreamReader(in));
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("SELECT TO_CHAR(bday,'DD/MM/yyyy hh24:mi') FROM TEST2");
while (rs.next())
System.out.println(rs.getString(1));
rs.close();
stat.close();
conn.commit();
conn.close();
//accessed using url jdbc:h2:tcp://localhost/mem:db1
try
CachedRowSet crs = new DBConnector().executeQuery("select * from test2");
while(crs.next())
System.out.println("ARGUMENT_NAME:"+crs.getString(1));
// System.out.println(",DATA_TYPE:"+crs.getString("DATA_TYPE"));
crs.close();
catch(SQLException e)
e.printStackTrace();
catch (Exception e) //this exception gets throws connection failed!
System.out.println("Exception initializing memory H2 database"+e);
我稍后在同一个 JVM 中通过 url jdbc:h2:mem:db1
访问,这也可以正常工作。但是当我想通过 jdbc:h2:tcp://localhost/mem:db1
访问它时,它在同一个 JVM 或不同的 JVM 中都不起作用。
我实际上想以嵌入式模式运行系统并使用控制台查看内容。如果我以相同的 servlet 上下文启动方法启动网络服务器,我可以看到控制台,但它仍然没有使用 url jdbc:h2:tcp://localhost/mem:db1
连接到内存数据库。
如果我使用命令行启动服务器
java -cp "WebContent/WEB-INF/lib/h2-1.3.148.jar;hsqldb.jar;%H2DRIVERS%;%CLASSPATH%" org.h2.tools.Console %*
and url as 'jdbc:h2:tcp://localhost/mem:db1'
然后尝试连接,令人惊讶的是它连接但没有数据。似乎它正在自己创建一个单独的服务器和一个不同的数据库。所以没有数据。
【问题讨论】:
【参考方案1】:要使内存数据库可用于另一个进程,您需要在打开数据库的同一进程中启动 TCP 服务器。示例:
package db;
import java.sql.Connection;
import java.sql.DriverManager;
import org.h2.tools.Server;
public class TestMem
public static void main(String... args) throws Exception
// open the in-memory database within a VM
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection("jdbc:h2:mem:test");
conn.createStatement().execute("create table test(id int)");
// start a TCP server
// (either before or after opening the database)
Server server = Server.createTcpServer().start();
// .. use in embedded mode ..
// or use it from another process:
System.out.println("Server started and connection is open.");
System.out.println("URL: jdbc:h2:" + server.getURL() + "/mem:test");
// now start the H2 Console here or in another process using
// java org.h2.tools.Console -web -browser
System.out.println("Press [Enter] to stop.");
System.in.read();
System.out.println("Stopping server and closing the connection");
server.stop();
conn.close();
【讨论】:
是的,我已经启动并运行了这个。与您的建议的唯一区别是我刚刚启动了 Web 服务器webserver = Server.createWebServer().start();
的控制台部分,我想问题是在相同的进程中启动 tcp 服务器。同样的过程非常关键。以上是关于内存模式下的H2数据库无法被Console访问的主要内容,如果未能解决你的问题,请参考以下文章
PostgreSQL模式下的h2数据库不接受PostgreSQL SQL语法
播放框架2:内存数据库中的h2 mysql兼容模式:转义字符