Как показать содержимое локальной базы данных h2 (веб-консоль)?

Недавно я присоединился к новой команде, и здесь парни используют h2 для обслуживания заглушки.

Мне было интересно, могу ли я показать содержимое этой базы данных с помощью веб-интерфейса. На работе это доступно, перейдя в localhost:5080

У меня есть проект, в котором я использую базу данных h2, но не могу увидеть веб-консоль h2, когда нажимаю localhost:5080

Я пробовал также localhost:8082 - это тоже не работает.

Конфигурация моего проекта (работает успешно):

     <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"/>

У меня нет идей, как получить доступ к веб-консоли h2. пожалуйста помоги.

PS

Я вижу упоминания о h2 только в .m2 папка

PS2

Я заметил, что веб-консоль доступна http://localhost:8082/ Если заменить URL в конфигурации с:

<property name="url" value="jdbc:h2:tcp://localhost/~/test;MODE=PostgreSQL" />

Но это работает, если я уже запускаю h2 (в .m2 папка найти h2 файл фляги и двойной щелчок)

Если 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)
    ...

Я хочу добиться того, чтобы h2 запускался, если он не запускался при запуске приложения.

PS3

Я попытался написать следующий код:

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);
 }

Я выполняю это и после того, как я пытаюсь напечатать localhost:9092 в моем браузере.

В данный момент загружается файл. Внутри файла следующий контент:

Version mismatch, driver version is “0” but server version is “15”

моя версия h2 1.4.182

PS4

Этот код работает:

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();
    }
}

но мне нужно вызывать его только тогда, когда активен конкретный пружинный профиль (теперь он работает всегда)

3 ответа

Решение

Давайте разделим вопрос на две части.

В зависимости от того, как вы указали соединение с H2, вы получите разные режимы работы.

Режимы: встроенный, в памяти, сервер.

jdbc:h2:~/test дает вам экземпляр H2 во встроенном режиме. Встроенный режим имеет ограничение на доступ только через тот же загрузчик классов и ту же JVM ( доказательство)

jdbc:h2:mem:test дает вам экземпляр H2 в памяти. Это также не доступно из внешнего мира.

jdbc:h2:tcp://localhost/test запустит сервер H2, и он будет доступен вне режима сервера JVM, но с одним ограничением - сервер должен быть запущен до установления соединения.

Последнее ограничение вызывает ваши Connection refused: connect: localhost" исключение.

Подводя итог все:

  • Запустите сервер H2, прежде чем запускать приложение
  • использование jdbc:h2:tcp://localhost/test как строка подключения
  • ....
  • счастливого кодирования:)

Обновить

Просто заметил, что вы хотите запустить сервер в процессе запуска приложения.

Вы можете сделать это несколькими способами, в зависимости от того, как вы запускаете приложение:

  • Если вы используете maven / gradle, вам будет проще добавить какой-нибудь профиль / задачу, чтобы она выполнялась до того, как приложение действительно запустится.
  • Если вам нужно все настроить в Java, я предлагаю вам взглянуть на этот вопрос

Обновление 2

Если подключение к локальной базе данных требуется только для целей разработки / отладки, я бы все настроил, используя профиль maven. Ответы на этот вопрос решат это.

Если вам нужен доступ к базе данных H2 в производственном режиме (я вряд ли смогу представить какой-либо вариант использования для этого), лучше сделать это весной. Главным образом потому, что настройка контейнера приложения / среды, вероятно, будет отличаться в рабочей среде (по сравнению со средой разработки).

Чтобы решить вопрос о том, запускать сервер вне контекста Spring или нет - все зависит от требований. Стоит отметить, что сервер должен быть запущен до запуска источника данных (в противном случае контекст весны не будет загружен).

Обновление 3

К сожалению, я не могу дать вам рабочее решение, но согласно JavaDocs есть разница между TCP-сервером и веб-сервером. Присмотритесь к JavaDoc класса H2 Server.

Я думаю, вы должны использовать Server.createWebServer() способ создания сервера (разница между TCP-сервером и веб-сервером заключается в том, что

Еще один замечательный класс, который вы могли бы использовать org.h2.tools.Console ( JavaDoc здесь) Просто запустите основной метод консоли, и я думаю, что это должно решить все.

Вы должны иметь возможность использовать варианты в памяти или на основе файлов, а затем в своем приложении запустить сервер TCP TCP отдельно, например, с помощью bean-компонента Spring (обратите внимание на полупсевдокод и пример порта):

@Component
class Bootstrap {
    @PostConstruct
    public void startH2TcpServer() {
         Server.createTcpServer("-tcpPort", "9123", "-tcpDaemon").start();
    }
}

См. http://www.h2database.com/html/tutorial.html.

Как насчет изменения URL JDBC в конфигурации, чтобы включить

AUTO_SERVER=TRUE 

начать h2 автоматически.

См. Авто смешанный режим

Несколько процессов могут обращаться к одной и той же базе данных без необходимости запуска сервера вручную. Для этого добавьте;AUTO_SERVER=TRUE к URL базы данных. Вы можете использовать один и тот же URL базы данных независимо от того, открыта ли база данных или нет. Эта функция не работает с базами данных в памяти.

Используйте один и тот же URL для всех подключений к этой базе данных. Внутренне, при использовании этого режима, первое соединение с базой данных выполняется во встроенном режиме, и дополнительно сервер запускается изнутри (как поток демона). Если база данных уже открыта в другом процессе, режим сервера используется автоматически.

Другие вопросы по тегам