【问题标题】:View content of H2 or HSQLDB in-memory database查看 H2 或 HSQLDB 内存数据库的内容
【发布时间】:2023-03-24 08:58:02
【问题描述】:

有没有办法浏览 H2 或 HSQLDB 内存数据库的内容以供查看?例如,在与 Hibernate 的调试会话期间,以检查何时执行刷新;或确保实例化数据库的脚本给出预期的结果。

是否存在可以嵌入到代码中的插件或库以允许这样做?

请提及您正在谈论的是哪一个(H2 或 HSQLDB),以防您对其中一个有特定的答案。

【问题讨论】:

标签: hsqldb h2 in-memory-database


【解决方案1】:

您可以在将访问相同内存数据库的应用程序中运行 H2 web server。您还可以使用任何通用 JDBC 客户端(例如 SquirrelSQL)访问在服务器模式下运行的 H2。

更新:

Server webServer = Server.createWebServer("-web,-webAllowOthers,true,-webPort,8082").start();
Server server = Server.createTcpServer("-tcp,-tcpAllowOthers,true,-tcpPort,9092").start();

现在您可以在同一进程中通过jdbc:h2:mem:foo_db URL 连接到您的数据库,或使用localhost:8082 浏览foo_db 数据库。记得关闭两台服务器。另见:H2 database in memory mode cannot be accessed by Console

你也可以使用 Spring:

<bean id="h2Server" class="org.h2.tools.Server" factory-method="createTcpServer" init-method="start" destroy-method="stop" depends-on="h2WebServer">
    <constructor-arg value="-tcp,-tcpAllowOthers,true,-tcpPort,9092"/>
</bean>
<bean id="h2WebServer" class="org.h2.tools.Server" factory-method="createWebServer" init-method="start" destroy-method="stop">
    <constructor-arg value="-web,-webAllowOthers,true,-webPort,8082"/>
</bean>

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" depends-on="h2Server">
    <property name="driverClass" value="org.h2.Driver"/>
    <property name="jdbcUrl" value="jdbc:h2:mem:foo_db"/>
</bean>

顺便说一句,您应该只依赖断言而不是手动查看数据库内容。仅用于故障排除。

注意如果您使用 Spring 测试框架,您将不会看到正在运行的事务所做的更改,并且该事务将在测试后立即回滚。

【讨论】:

  • 我收到“true”是无效选项的错误。 -webAllowOthers 是否使用过参数?使用最新的 H2 代码,它不带任何参数。看这里的“main”方法:h2database.com/javadoc/org/h2/tools/Server.html
  • 就像 hman 提到的,最新版本不接受“true”参数,所以删除它:&lt;constructor-arg value="-web,-webAllowOthers,-webPort,8082"/&gt;
  • 新版本遵循Server.createTcpServer("-tcpPort" ,"9092", "-tcpAllowOthers")Server.createWebServer("-webPort", "8082", "-tcpAllowOthers")的单独参数约定
  • 在纯Java中,您必须删除“true”参数,并像这样分隔参数:Server.createWebServer("-web", "-webAllowOthers", "-webPort", "8082").start();
  • 使用 Spring Boot,您可以在 application.properties 文件中简单地设置“h2.console.enabled: true”和“h2.console.path: h2-console”。
【解决方案2】:

对于 H2,如果您有数据库连接对象,则可以在调试会话期间start a web server within your code。您可以将此行添加到您的代码中,或作为“监视表达式”(动态):

org.h2.tools.Server.startWebServer(conn);

服务器工具将在本地启动一个网络浏览器,允许您访问数据库。

【讨论】:

  • 对使用Spring Data的人的评论-您可以通过这种方式从ApplicationContext获取连接:((DataSource)context.getBean("dataSource")).getConnection()
  • 这在 JUnit TestWatcher @Rule 中也很棒
  • 如果您在调试时在 intelliJ 中使用“evaluateExpression”启动它,它甚至可以工作。 (锁定其余手表直到停止)
  • 我将DataSource 实例自动连接到我的测试用例中,并添加了一个主体为org.h2.tools.Server.startWebServer(dataSource.getConnection()); 的方法。现在评估该方法会打开浏览器。请注意,这会导致执行休眠,直到您断开连接(浏览器中的左上角图标)!
【解决方案3】:

在 H2 中,对我有用的是:

我编码,像这样启动服务器:

server = Server.createTcpServer().start();

这会在 localhost 端口 9092 上启动服务器。

然后,在代码中,在以下 JDBC URL 上建立数据库连接:

jdbc:h2:tcp://localhost:9092/mem:test;DB_CLOSE_DELAY=-1;MODE=MySQL

调试时,作为客户端检查数据库,我使用H2提供的数据库,足够好,启动它只需要单独启动以下java main

org.h2.tools.Console

这将在 8082 上启动一个带有应用程序的 Web 服务器,在 localhost:8082 上启动一个浏览器

然后就可以输入之前的URL查看DB了

【讨论】:

    【解决方案4】:

    使用 HSQLDB,您有几个内置选项。

    有两个 GUI 数据库管理器和一个数据库的命令行界面。这些类是:

    org.hsqldb.util.DatabaseManager
    org.hsqldb.util.DatabaseManagerSwing
    org.hsqldb.cmdline.SqlTool
    

    您可以从您的应用程序启动上述任一操作并访问内存数据库。

    这里给出了一个 JBoss 的例子:

    http://docs.jboss.org/jbpm/v3.2/userguide/html/ch07s03.html

    您还可以使用您的应用程序启动服务器,将其指向内存数据库。

    org.hsqldb.Server
    

    【讨论】:

    【解决方案5】:

    对于 HSQLDB,以下对我有用:

    DatabaseManager.threadedDBM();
    

    一旦我将它指向正确的名为 in-mem 的数据库,它就会用我的表和数据调出 GUI。

    这基本上相当于新建一个DatabaseManager(非Swing 变体),它会提示连接详细信息,并设置为--noexit

    我也尝试了 Swing 版本,但它只有一个 main,我不确定要传递的参数。如果有人知道,请在这里发帖。

    仅仅因为我搜索了几个小时以找到正确的数据库名称:数据库的名称就是您的数据源的名称。因此,如果您有一个 id=dataSource 的数据源 bean,请尝试使用 URL jdbc:hsqldb:mem:dataSource。如果这不起作用,请尝试使用默认的 testdb。

    【讨论】:

    • org.hsqldb.util.DatabaseManagerSwing.main(new String[] { "--url", URL, "--user", USERNAME, "--password", PASSWORD});
    • 这里是对参数的一些解释:stackoverflow.com/a/3076005/32453
    【解决方案6】:

    您可以将其公开为 JMX 功能,可通过 JConsole 启动:

    @ManagedResource
    @Named
    public class DbManager {
    
        @ManagedOperation(description = "Start HSQL DatabaseManagerSwing.")
        public void dbManager() {
            String[] args = {"--url", "jdbc:hsqldb:mem:embeddedDataSource", "--noexit"};
            DatabaseManagerSwing.main(args);
        }
    }
    

    XML 上下文:

    <context:component-scan base-package="your.package.root" scoped-proxy="targetClass"/>
    <context:annotation-config />
    <context:mbean-server />
    <context:mbean-export />
    

    【讨论】:

      【解决方案7】:

      这是一个 Play 2 控制器,用于初始化 H2 TCP 和 Web 服务器:

      package controllers;
      
      import org.h2.tools.Server;
      import play.mvc.Controller;
      import play.mvc.Result;
      
      import java.sql.SQLException;
      
      /**
       * Play 2 controller to initialize H2 TCP Server and H2 Web Console Server.
       *
       * Once it's initialized, you can connect with a JDBC client with
       * the URL `jdbc:h2:tcp://127.0.1.1:9092/mem:DBNAME`,
       * or can be accessed with the web console at `http://localhost:8082`,
       * and the URL JDBC `jdbc:h2:mem:DBNAME`.
       *
       * @author Mariano Ruiz <mrsarm@gmail.com>
       */
      public class H2ServerController extends Controller {
      
          private static Server h2Server = null;
          private static Server h2WebServer = null;
      
          public static synchronized Result debugH2() throws SQLException {
              if (h2Server == null) {
                  h2Server = Server.createTcpServer("-tcp", "-tcpAllowOthers", "-tcpPort", "9092");
                  h2Server.start();
                  h2WebServer = Server.createWebServer("-web","-webAllowOthers","-webPort","8082");
                  h2WebServer.start();
                  return ok("H2 TCP/Web servers initialized");
              } else {
                  return ok("H2 TCP/Web servers already initialized");
              }
          }
      }
      

      【讨论】:

        【解决方案8】:

        我在使用Connection is broken: "unexpected status 16843008" 与 inMemory(以及文件中)远程连接 H2 版本 1.4.190 时遇到问题,直到不要降级到 1.3.176。见Grails accessing H2 TCP server hangs

        【讨论】:

          【解决方案9】:

          这更像是对之前 Thomas Mueller 帖子的评论,而不是答案,但没有得到足够的声誉。如果您是 Spring JDBC 模板,另一种获取连接的方法是使用以下方法:

          jdbcTemplate.getDataSource().getConnection();
          

          所以在调试模式下,如果您添加到 Eclipse 中的“表达式”视图,它将打开浏览器,显示 H2 控制台:

          org.h2.tools.Server.startWebServer(jdbcTemplate.getDataSource().getConnection());
          

          Eclipse Expressions View

          H2 Console

          【讨论】:

            【解决方案10】:

            我不知道为什么它在你的机器上运行良好,但我必须花一天时间才能让它正常运行。

            服务器通过 url "jdbc:h2:tcp://localhost:9092/~/default" 使用 Intellij Idea U。

            “localhost:8082”在浏览器中也可以正常工作。

            我将此添加到 mvc-dispatcher-servlet.xml 中

            <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" depends-on="h2Server">
                <property name="driverClassName" value="org.h2.Driver"/>
                <property name="url" value="jdbc:h2:tcp://localhost:9092/~/default"/>
                <property name="username" value="sa"/>
                <property name="password" value=""/>
            </bean>
            
            <bean id="h2Server" class="org.h2.tools.Server" factory-method="createTcpServer" init-method="start" destroy-method="stop" depends-on="h2WebServer">
                <constructor-arg>
                    <array>
                        <value>-tcp</value>
                        <value>-tcpAllowOthers</value>
                        <value>-tcpPort</value>
                        <value>9092</value>
                    </array>
                </constructor-arg>
            </bean>
            
            <bean id="h2WebServer" class="org.h2.tools.Server" factory-method="createWebServer" init-method="start" destroy-method="stop">
                <constructor-arg>
                    <array>
                        <value>-web</value>
                        <value>-webAllowOthers</value>
                        <value>-webPort</value>
                        <value>8082</value>
                    </array>
                </constructor-arg>
            </bean>
            

            【讨论】:

              【解决方案11】:

              如何通过 ODBC 和 MS-Access、Excel 轻松查看(以及编辑)内容? 软件版本::

              • H2 版本:1.4.196
              • Win 10 Postgres ODBC 驱动程序版本:psqlodbc_09_03_0210
              • 对于 Win7 ODBC 客户端:win7_psqlodbc_09_00_0101-x64.msi

              H2 服务器:

              /*
              For JDBC Clients to connect:
              jdbc:h2:tcp://localhost:9092/trader;CIPHER=AES;IFEXISTS=TRUE;MVCC=true;LOCK_TIMEOUT=60000;CACHE_SIZE=131072;CACHE_TYPE=TQ
              */
              public class DBStarter {
                  public static final String BASEDIR = "/C:/Trader/db/";
                  public static final String DB_URL = BASEDIR + "trader;CIPHER=AES;IFEXISTS=TRUE;MVCC=true;LOCK_TIMEOUT=10000;CACHE_SIZE=131072;CACHE_TYPE=TQ";
              
                static void startServer() throws SQLException {
                      Server tcpServer = Server.createTcpServer(
                              "-tcpPort", "9092",
                              "-tcpAllowOthers",
                              "-ifExists",
              //                "-trace",
                              "-baseDir", BASEDIR
                      );
                      tcpServer.start();
                      System.out.println("H2 JDBC Server started:  " + tcpServer.getStatus());
              
                      Server pgServer = Server.createPgServer(
                              "-pgPort", "10022",
                              "-pgAllowOthers",
                              "-key", "traderdb", DB_URL
                      );
                      pgServer.start();
                      System.out.println("H2 ODBC PGServer started: " + pgServer.getStatus());
              
                  }
              }   
              

              任何 ODBC 客户端都可以使用的 Windows10 ODBC 数据源配置: 在数据库字段中,必须使用“-key”参数中给出的名称。

              【讨论】:

                猜你喜欢
                • 2016-10-02
                • 1970-01-01
                • 1970-01-01
                • 2019-12-07
                • 2013-07-22
                • 1970-01-01
                • 1970-01-01
                • 2019-07-06
                • 2013-03-30
                相关资源
                最近更新 更多