代码之家  ›  专栏  ›  技术社区  ›  roufamatic RichardJohnn

从maven启动h2数据库服务器?

  •  36
  • roufamatic RichardJohnn  · 技术社区  · 15 年前

    假设我想为集成测试创建和使用h2数据库。

    Maven有一个命令来运行测试: mvn test .

    有没有方法告诉Maven启动h2数据库服务器进行测试,并在测试完成后停止它?

    我想象这和我如何通过maven命令运行Tomcat类似。( mvn tomcat:run )。

    对不起,如果这个问题是胡说,我仍然在围绕新的概念绞尽脑汁。

    9 回复  |  直到 11 年前
        1
  •  18
  •   roufamatic RichardJohnn    15 年前

    我可以让它在不使用外部服务器的情况下工作,只需通过maven将依赖项添加到h2,然后使用这个bean:

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.h2.Driver"/>
        <property name="url" value="jdbc:h2:file:h2\db"/>
        <property name="username" value="sa"/>
        <property name="password" value=""/>        
    </bean>
    

    同样,这要求我使用基于文件的数据库而不是内存中的数据库。但它起了作用。

        2
  •  12
  •   Stefan De Boey    15 年前

    您可以使用启动和停止数据库的主要方法创建两个小类。其思想是在运行集成测试之前运行startserver类,然后在运行测试之后运行stopserver类。

    您应该为您的DB服务器做同样的事情,如中所述。 this document (说明用于在集成测试中启动和停止码头)

    在pom.xml中,应该定义maven exec插件来运行 exec:java 目标并创建2个执行(1个用于调用StartServer,1个用于StopServer):

    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>exec-maven-plugin</artifactId>
      <version>1.1.1</version>
      <executions>
        <execution>
          <!-- start server before integration tests -->
          <id>start</id>
          <phase>pre-integration-test</phase>
          <goals>
            <goal>java</goal>
          </goals>
          <configuration>
            <mainClass>com.foo.StartServer</mainClass>
          </configuration>
         </execution>
         <execution>
          <!-- stop server after integration tests -->
          <id>stop</id>
          <phase>post-integration-test</phase>
          <goals>
            <goal>java</goal>
          </goals>
          <configuration>
            <mainClass>com.foo.StopServer</mainClass>
          </configuration>
         </execution>
       </executions>
     </plugin>
    

    希望这就是你想要的

        3
  •  8
  •   Sebastien Lorber    12 年前

    在集成测试(默认插件阶段)之前,此插件可以通过TCP模式生成新的h2 db: h2-maven-plugin on github

    它没有很好的文档记录,但是您可以检查mojo源以了解配置选项。它在Maven Central上发布。


    基本上,对于集成测试,您可能希望Maven:

    • 为Tomcat服务器和H2保留随机可用的网络端口(以避免端口冲突)
    • 启动H2服务器
    • 启动Tomcat服务器
    • 运行集成测试
    • 停止Tomcat服务器
    • 停止H2服务器

    这可以通过类似这样的Maven配置来实现。 假设集成测试是用自定义接口JUnit类别注释的:

    @Category(IntegrationTest.class)
    

    这个Maven配置对我来说很好:

    <profile>
       <id>it</id>
       <build>
         <plugins>
    
           <!-- Reserve randomly available network ports -->
           <plugin>
             <groupId>org.codehaus.mojo</groupId>
             <artifactId>build-helper-maven-plugin</artifactId>
             <executions>
               <execution>
                 <id>reserve-network-port</id>
                 <goals>
                   <goal>reserve-network-port</goal>
                 </goals>
                 <phase>process-resources</phase>
                 <configuration>
                   <portNames>
                     <portName>tomcat.test.http.port</portName>
                     <portName>h2.test.tcp.port</portName>
                   </portNames>
                 </configuration>
               </execution>
             </executions>
           </plugin>
    
    
           <!-- Start H2 before integration tests, accepting tcp connections on the randomly selected port -->
           <plugin>
             <groupId>com.edugility</groupId>
             <artifactId>h2-maven-plugin</artifactId>
             <version>1.0</version>
             <configuration>
               <port>${h2.test.tcp.port}</port>
             </configuration>
             <executions>
                 <execution>
                   <id>Spawn a new H2 TCP server</id>
                   <goals>
                     <goal>spawn</goal>
                   </goals>
                 </execution>
                 <execution>
                   <id>Stop a spawned H2 TCP server</id>
                   <goals>
                     <goal>stop</goal>
                   </goals>
                 </execution>
               </executions>
           </plugin>
    
    
           <!-- Start Tomcat before integration tests on the -->
           <plugin>
             <groupId>org.apache.tomcat.maven</groupId>
             <artifactId>tomcat7-maven-plugin</artifactId>
             <configuration>
               <systemProperties>
                 <spring.profiles.active>integration_tests</spring.profiles.active>
                 <httpPort>${http.test.http.port}</httpPort>
                 <h2Port>${h2.test.tcp.port}</h2Port>
               </systemProperties>
               <port>${http.test.http.port}</port>
               <contextFile>src/main/java/META-INF/tomcat/webapp-test-context-using-h2.xml</contextFile>
               <fork>true</fork>
             </configuration>
             <executions>
               <execution>
                 <id>run-tomcat</id>
                 <phase>pre-integration-test</phase>
                 <goals>
                   <goal>run</goal>
                 </goals>
               </execution>
               <execution>
                 <id>stop-tomcat</id>
                 <phase>post-integration-test</phase>
                 <goals>
                   <goal>shutdown</goal>
                 </goals>
               </execution>
             </executions>
             <dependencies>
               <dependency>
                 <groupId>mysql</groupId>
                 <artifactId>mysql-connector-java</artifactId>
                 <version>${mysql.version}</version>
               </dependency>
               <dependency>
                 <groupId>com.h2database</groupId>
                 <artifactId>h2</artifactId>
                 <version>${h2.version}</version>
               </dependency>
             </dependencies>
           </plugin>
    
    
           <!-- Run the integration tests annotated with @Category(IntegrationTest.class) -->
           <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-failsafe-plugin</artifactId>
             <!-- Bug in 2.12.x -->
             <version>2.11</version>
             <dependencies>
               <dependency>
                 <groupId>org.apache.maven.surefire</groupId>
                 <artifactId>surefire-junit47</artifactId>
                 <version>2.12.4</version>
               </dependency>
             </dependencies>
             <configuration>
               <groups>com.mycompany.junit.IntegrationTest</groups>
               <failIfNoTests>false</failIfNoTests>
               <junitArtifactName>junit:junit-dep</junitArtifactName>
               <systemPropertyVariables>
                 <httpPort>${tomcat.test.http.port}</httpPort>
                 <h2Port>${h2.test.tcp.port}</h2Port>
               </systemPropertyVariables>
             </configuration>
             <executions>
               <execution>
                 <goals>
                   <goal>integration-test</goal>
                 </goals>
               </execution>
             </executions>
           </plugin>
    
         </plugins>
       </build>
     </profile>
    

    您可能希望在tomcat上下文文件上使用maven过滤器,以便替换端口:

       <contextFile>src/main/java/META-INF/tomcat/webapp-test-context-using-h2.xml</contextFile>
    

    文件内容为:

      <Resource name="jdbc/dataSource"
                auth="Container"
                type="javax.sql.DataSource"
                maxActive="100"
                maxIdle="30"
                maxWait="10000"
                username=""
                password=""
                driverClassName="org.h2.Driver"
                url="jdbc:h2:tcp://localhost:${h2.test.tcp.port}/mem:db;DB_CLOSE_ON_EXIT=FALSE;MODE=MySQL"/>
    

    或者,如果不需要JNDI数据源,可以使用Spring声明的数据源,使用相同的属性…


    如果您希望能够设置集成测试Tomcat,并从您的IDE中运行集成测试,则需要额外的一次旅行:

    您可以使用属性来分叉或不分叉Tomcat服务器:

    <fork>${integrationTestsForkTomcatJvm}</fork>
    

    当您设置fork=false时,服务器将阻塞,Maven将不继续,因此集成测试将不会运行,但您将能够从IDE运行它们。

        4
  •  5
  •   Ruslan Pilin    14 年前

    我刚刚启动了maven@bitback的h2插件项目。我会感谢你的帮助。

    https://bitbucket.org/dohque/maven-h2-plugin

    希望能有所帮助。

        5
  •  4
  •   Romain Linsolas    15 年前

    在我的项目中,对于单元测试,我要求Spring处理这个数据库创建和初始化。如中所述 H2 documentation ,您可以为此创建一个bean:

    <bean id = "org.h2.tools.Server"
        class="org.h2.tools.Server"
        factory-method="createTcpServer"
        init-method="start"
        destroy-method="stop">
        <constructor-arg value="-tcp,-tcpAllowOthers,true,-tcpPort,8043" />
    </bean>
    

    当您开始单元测试时,只需使用这个配置启动Spring上下文。

        6
  •  4
  •   John Q Citizen    12 年前

    在运行单元测试之前,我创建了一个基于文件的h2数据库。文件保存在 target 目录,可以随时使用 mvn clean .

    我使用Maven SQL插件如下:

    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>sql-maven-plugin</artifactId>
      <version>1.5</version>
      <dependencies>
        <dependency>
          <groupId>com.h2database</groupId>
          <artifactId>h2</artifactId> 
          <version>1.3.166</version>
        </dependency>
      </dependencies>
      <configuration>
        <driver>org.h2.Driver</driver>
        <url>jdbc:h2:file:target/db/testdb</url>
        <username>sa</username>
        <password></password>
        <autocommit>true</autocommit>
        <skip>${maven.test.skip}</skip>
      </configuration>
      <executions>
        <execution>
          <id>create-db</id>
          <phase>process-test-resources</phase>
          <goals>
            <goal>execute</goal>
          </goals>
          <configuration>
            <srcFiles>
              <srcFile>${sql.dir}/drop_db.sql</srcFile>
              <srcFile>${sql.dir}/tables.sql</srcFile>
              <srcFile>${sql.dir}/constraints.sql</srcFile>
              ... etc ...
            </srcFiles>
          </configuration>
        </execution>
      </executions>
    </plugin>
    

    可以通过运行 mvn process-test-resources . 运行测试时,请确保连接到中的数据库 target/db/testdb 通过休眠属性。

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
          destroy-method="close"
          p:driverClassName="org.h2.Driver"
          p:url="jdbc:h2:file:target/db/testdb"
          p:username="sa"
          p:password="" />
    

    您还需要在Maven的依赖项中依赖com.h2database.h2。

        7
  •  3
  •   fuemf5    13 年前

    如果您想在内存中创建它,那么只需使用一个不同的URL:

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.h2.Driver"/>
        <property name="url" value="jdbc:h2:mem:db"/>
        <property name="username" value="sa"/>
        <property name="password" value=""/>        
    </bean>
    

    您可以提供其他选项,例如:;db_close_delay=-1

    见: http://www.h2database.com/html/features.html#in_memory_databases

        8
  •  1
  •   uthark    15 年前

    因为h2不提供maven插件,所以应该使用maven-antrun插件启动它。在Ant任务中编写启动和停止h2引擎的代码,并在集成测试启动和停止时调用它。

    详见 http://docs.codehaus.org/display/MAVENUSER/Maven+and+Integration+Testing

        9
  •  1
  •   Peter Butkovic    11 年前

    以下是我的工作(只是用 h2 依赖关系和 exec-maven-plugin ):

        <build>
            <plugins>
                <!-- start/stop H2 DB as a server -->
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <version>1.2.1</version>
                    <executions>
                        <execution>
                            <id>start-h2</id>
                            <phase>pre-integration-test</phase>
                            <goals>
                                <goal>java</goal>
                            </goals>
                            <configuration>
                                <mainClass>org.h2.tools.Server</mainClass>
                                <arguments>
                                    <argument>-tcp</argument>
                                    <argument>-tcpDaemon</argument>
                                </arguments>
                            </configuration>
                        </execution>
                        <execution>
                            <id>stop-h2</id>
                            <phase>post-integration-test</phase>
                            <goals>
                                <goal>java</goal>
                            </goals>
                            <configuration>
                                <mainClass>org.h2.tools.Server</mainClass>
                                <arguments>
                                    <argument>-tcpShutdown</argument>
                                    <argument>tcp://localhost:9092</argument>
                                </arguments>
                            </configuration>
                        </execution>
                    </executions>
                    <configuration>
                        <includeProjectDependencies>true</includeProjectDependencies>
                        <includePluginDependencies>true</includePluginDependencies>
                        <executableDependency>
                            <groupId>com.h2database</groupId>
                            <artifactId>h2</artifactId>
                        </executableDependency>
                    </configuration>
                    <dependencies>
                        <dependency>
                            <groupId>com.h2database</groupId>
                            <artifactId>h2</artifactId>
                            <version>1.3.173</version>
                        </dependency>
                    </dependencies>
                </plugin>
            </plugins>
    </build>
    

    请注意,在我的 pom.xml 这个 com.h2database:h2 不是项目依赖项。 如果您拥有它,您可能不需要显式地将其命名为插件依赖项。