Java 如何显示本地 h2 数据库(Web 控制台)的内容?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34238142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to show content of local h2 database(web console)?
提问by gstackoverflow
Recently I joined a new team and here guys use h2 for stub service.
最近我加入了一个新团队,这里的人使用 h2 进行存根服务。
I was wondering whether I can show the content of this database using web interface. At work it is available by going to localhost:5080
我想知道是否可以使用 Web 界面显示该数据库的内容。在工作中,它可以通过去localhost:5080
I have a project where I use h2 database, but I cannot see the h2 web console when I hit localhost:5080
我有一个使用 h2 数据库的项目,但是当我点击时我看不到 h2 web 控制台 localhost:5080
I tried also localhost:8082
- it also doesn't work.
我也试过localhost:8082
- 它也不起作用。
My project configuration (works successfully):
我的项目配置(成功运行):
<bean id="wrappedDataSource" class="net.bull.javamelody.SpringDataSourceFactoryBean">
<property name="targetName" value="dataSource" />
</bean>
<bean id="wrappedDataSource" class="net.bull.javamelody.SpringDataSourceFactoryBean">
<property name="targetName" value="dataSource" />
</bean>
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:~/test;MODE=PostgreSQL" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="wrappedDataSource"/>
<property name="configLocation">
<value>classpath:hibernate-test.cfg.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hbm2ddl.auto">create-drop</prop>
</props>
</property>
</bean>
<context:property-placeholder location="classpath:jdbc.properties"/>
I have not ideas how to access to h2 web console. please help.
我不知道如何访问 h2 web 控制台。请帮忙。
P.S.
聚苯乙烯
I see mentions of h2 only in .m2
folder
我只在.m2
文件夹中看到提到 h2
P.S.2
PS2
I noticed that web console available by http://localhost:8082/
if replace url in configuration with:
我注意到http://localhost:8082/
如果将配置中的 url 替换为:
<property name="url" value="jdbc:h2:tcp://localhost/~/test;MODE=PostgreSQL" />
Butit works if I already start h2(in .m2
folder find h2
jar file and hit double click)
但是如果我已经启动了 h2,它就可以工作(在.m2
文件夹中找到h2
jar 文件并双击)
If h2 is not started when I start application - i see following error:
如果启动应用程序时 h2 未启动 - 我看到以下错误:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:94)
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dbInitializer': Invocation of init method failed; nested exception is org.hibernate.exception.GenericJDBCException: Could not open connection
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136)
...
Caused by: org.hibernate.exception.GenericJDBCException: Could not open connection
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
...
Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Соединение разорвано: "java.net.ConnectException: Connection refused: connect: localhost"
Connection is broken: "java.net.ConnectException: Connection refused: connect: localhost" [90067-182])
at org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1549)
...
Caused by: org.h2.jdbc.JdbcSQLException: Соединение разорвано: "java.net.ConnectException: Connection refused: connect: localhost"
Connection is broken: "java.net.ConnectException: Connection refused: connect: localhost" [90067-182]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
...
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
...
I want to achieve that h2 starts if it not started when I start my application.
如果在我启动我的应用程序时它没有启动,我想实现 h2 启动。
P.S.3
PS3
I have tried to wrote following code:
我尝试编写以下代码:
Server server = null;
try {
server = Server.createTcpServer("-tcpAllowOthers").start();
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection("jdbc:h2:tcp://localhost/~/test;MODE=PostgreSQL", "sa", "");
} catch (Exception e) {
LOG.error("Error while initialize", e);
}
I execute it and after I am trying to type localhost:9092
in my browser.
我执行它,然后我尝试localhost:9092
在浏览器中输入。
At this moment downloads file. inside file the following content:
这时下载文件。里面的文件如下内容:
Version mismatch, driver version is “0” but server version is “15”
my h2 version 1.4.182
我的 h2 版本 1.4.182
P.S.4
PS4
This code works:
此代码有效:
public class H2Starter extends ContextLoaderListener {
private static final Logger LOG = LoggerFactory.getLogger(H2Starter.class);
@Override
public void contextInitialized(ServletContextEvent event) {
startH2();
super.contextInitialized(event);
}
private static void startH2() {
try {
Server.createTcpServer("-tcpAllowOthers").start();
Class.forName("org.h2.Driver");
DriverManager.getConnection("jdbc:h2:tcp://localhost/~/test;MODE=PostgreSQL;AUTO_SERVER=TRUE", "sa", "");
Server.createWebServer().start();
} catch (Exception e) {
LOG.error("cannot start H2 [{}]", e);
}
}
public static void main(String[] args) {
startH2();
}
}
but I need to invoke it only when concrete spring profile active(now it works always)
但我只需要在混凝土弹簧轮廓处于活动状态时调用它(现在它始终有效)
采纳答案by WeMakeSoftware
Let's split the question into two parts.
让我们把问题分成两部分。
Depending on how you specify the connection to H2, you'll get different operational modes.
根据您指定与 H2 的连接的方式,您将获得不同的操作模式。
Modes are: Embedded, In-Memory, Server.
模式有:嵌入式、内存中、服务器。
jdbc:h2:~/test
gives you a H2 instance in embedded mode.
The embedded mode has a limitation of being accessible only through the same class loader and same JVM (proof)
jdbc:h2:~/test
为您提供嵌入模式的 H2 实例。嵌入模式有一个限制,即只能通过相同的类加载器和相同的 JVM 访问(证明)
jdbc:h2:mem:test
gets you an in-memory H2 instance. That is also notaccessible from outer world.
jdbc:h2:mem:test
为您提供内存中的 H2 实例。这也无法从外部世界访问。
jdbc:h2:tcp://localhost/test
will start H2 server and it will be accessiblefrom outside of JVM server modebut with one limitation - the server needs to be started before the connection is made.
jdbc:h2:tcp://localhost/test
将启动 H2 服务器,它可以从 JVM服务器模式之外访问,但有一个限制 - 服务器需要在建立连接之前启动。
The last limitation is causing your Connection refused: connect: localhost"
exception.
最后一个限制导致您的Connection refused: connect: localhost"
异常。
To sum everything up:
总结一切:
- start the H2 server beforeyou start application
- use
jdbc:h2:tcp://localhost/test
as connection string - ....
- happy coding :)
- 在启动应用程序之前启动H2 服务器
- 使用
jdbc:h2:tcp://localhost/test
的连接字符串 - ....
- 快乐编码:)
Update
更新
Just noticed that you want to start the server in the process of launching application.
刚刚注意到您要在启动应用程序的过程中启动服务器。
You can do that in several ways, depending how do you start the application:
您可以通过多种方式执行此操作,具体取决于您如何启动应用程序:
- If you're using maven / gradle it's easier for you to add some profile / task so that it gets executed before the application actually starts.
- If you have to setup everything in java, I suggest you look at this question
- 如果您使用的是 maven / gradle,则可以更轻松地添加一些配置文件 / 任务,以便在应用程序实际启动之前执行它。
- 如果你必须在java中设置一切,我建议你看看这个问题
Update 2
更新 2
If connection to the local database is needed only for developing / debugging purposes I would setup everything using maven profile. Answers from this questionwill solve that.
如果仅出于开发/调试目的需要连接到本地数据库,我将使用 maven 配置文件设置所有内容。这个问题的答案将解决这个问题。
If you need access to the H2 database in production (I can hardly imagine any use-case for that) it's better to do that in spring. Mainly because the application container / environment setup is likely to be different in production (compared to development environment).
如果您需要在生产中访问 H2 数据库(我几乎无法想象任何用例),最好在春季这样做。主要是因为应用程序容器/环境设置在生产中可能会有所不同(与开发环境相比)。
To address the question regarding if to start the server outside of Spring context or not - it all depends on the requirements. One thing you should note is that the server should be started beforethe datasource is started (otherwise the spring context will not load)
要解决有关是否在 Spring 上下文之外启动服务器的问题 - 这一切都取决于需求。你应该注意的一件事是服务器应该在数据源启动之前启动(否则 spring 上下文不会加载)
Update 3
更新 3
Unfortunately I'm not able to give you a working solution, but according to the JavaDocs there is a difference between TCP server and Web server. Take a closer look to the JavaDoc of H2 Server class.
不幸的是,我无法为您提供可行的解决方案,但根据 JavaDocs,TCP 服务器和 Web 服务器之间存在差异。仔细查看H2 Server 类的JavaDoc。
I guess you should use Server.createWebServer()
method to create the server (the difference between TCP server and Web server is that
我猜你应该使用Server.createWebServer()
方法来创建服务器(TCP服务器和Web服务器的区别在于
Another great class you could use org.h2.tools.Console
(JavaDoc here)
Just run the main method of Console and I guess that should solve everything.
您可以使用的另一个很棒的类org.h2.tools.Console
(此处为 JavaDoc)只需运行 Console 的 main 方法,我想这应该可以解决所有问题。
回答by Jukka
You ought to be able to use the in-memory or file-based variants, and then in your application fire up the H2 TCP server separately, e.g. using a Spring bean (mind the semi-pseudo code and sample port):
您应该能够使用内存中或基于文件的变体,然后在您的应用程序中单独启动 H2 TCP 服务器,例如使用 Spring bean(注意半伪代码和示例端口):
@Component
class Bootstrap {
@PostConstruct
public void startH2TcpServer() {
Server.createTcpServer("-tcpPort", "9123", "-tcpDaemon").start();
}
}
See http://www.h2database.com/html/tutorial.html#using_server
回答by Developer Marius ?il?nas
How about changing jdbc url in configuration to include
如何更改配置中的 jdbc url 以包含
AUTO_SERVER=TRUE
to start h2 automatically.
自动启动h2。
See Auto mixed mode
请参阅自动混合模式
Multiple processes can access the same database without having to start the server manually. To do that, append ;AUTO_SERVER=TRUE to the database URL. You can use the same database URL independent of whether the database is already open or not. This feature doesn't work with in-memory databases.
Use the same URL for all connections to this database. Internally, when using this mode, the first connection to the database is made in embedded mode, and additionally a server is started internally (as a daemon thread). If the database is already open in another process, the server mode is used automatically.
多个进程可以访问同一个数据库,而无需手动启动服务器。为此,请将 ;AUTO_SERVER=TRUE 附加到数据库 URL。无论数据库是否已打开,您都可以使用相同的数据库 URL。此功能不适用于内存数据库。
对该数据库的所有连接使用相同的 URL。在内部,当使用这种模式时,到数据库的第一个连接是在嵌入式模式下进行的,另外还有一个服务器在内部启动(作为一个守护线程)。如果数据库已经在另一个进程中打开,则自动使用服务器模式。