如何仅在数据库,模式和表尚不存在时自动创建

时间:2015-08-08 12:03:23

标签: hibernate jpa web-applications h2

我想创建一个简单的webapp

  • 允许远程客户端跟踪帖子请求中的某些内容
  • 将所有跟踪保留在轻量级数据库中
  • 在get请求中回复所有跟踪

关于数据库,我想

  1. 将其位置放在我的webapp的属性文件中(并将此位置用于persistence.xml中设置的hibernate.location.url)
  2. 如果数据库不存在则使用模式和表创建数据库
  3. 使用现有数据库和架构以及表和数据(如果存在)
  4. 所以我用:

    创建了一个maven项目

    的pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.my.tracker</groupId>
        <artifactId>tracker-webapp</artifactId>
        <version>0.1-SNAPSHOT</version>
        <packaging>war</packaging>
        <properties>
            <hibernate.version>4.3.8.Final</hibernate.version>
            <h2.version>1.4.185</h2.version>
        </properties>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-eclipse-plugin</artifactId>
                    <version>2.9</version>
                    <configuration>
                        <downloadSources>true</downloadSources>
                        <downloadJavadocs>false</downloadJavadocs>
                    </configuration>
                </plugin>
                <!-- Set a compiler level -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>2.6</version>
                </plugin>
            </plugins>
        </build>
    
        <dependencies>
            <!-- Servlet API -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
            <!-- JPA Provider (Hibernate) -->
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-entitymanager</artifactId>
                <version>${hibernate.version}</version>
            </dependency>
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-core</artifactId>
                <version>${hibernate.version}</version>
            </dependency>
            <!-- Database (H2) -->
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <version>${h2.version}</version>
            </dependency>
    
        </dependencies>
    
    </project>
    

    的src /主/资源/ META-INF / persistence.xml中

    <?xml version="1.0" encoding="UTF-8" ?>
    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
     http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
    
      <persistence-unit name="thePersistenceUnit" transaction-type="RESOURCE_LOCAL">
         <provider>org.hibernate.ejb.HibernatePersistence</provider>
    
        <class>org.my.tracker.Event</class>
    
        <properties>
            <property name="connection.driver_class" value="org.h2.Driver"/>
            <property name="hibernate.connection.url" value="jdbc:h2:./db/repository"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create"/>
            <property name="hibernate.show_sql" value="true" />
        </properties>
    </persistence-unit>
    </persistence>
    

    的src /主/ web应用/ WEB-INF / web.xml中

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <web-app 
       xmlns="http://java.sun.com/xml/ns/javaee" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
       version="2.5">
      <servlet>
        <servlet-name>orc-event</servlet-name>
        <servlet-class>org.my.tracker.EventServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>orc-event</servlet-name>
        <url-pattern>/event/*</url-pattern>
      </servlet-mapping>
    </web-app>
    

    的src /主/ JAVA /组织/我/跟踪器/ EventServlet.java

    package org.my.tracker;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.List;
    
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.Persistence;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.google.gson.Gson;
    
    public class EventServlet extends HttpServlet {
        private static final Logger LOGGER = LoggerFactory.getLogger(EventServlet.class);
    
        private static final long serialVersionUID = 1L;
        public static final String HTML_START="<html><body>";
        public static final String HTML_END="</body></html>";
        private static EntityManager manager;
    
        static {
            EntityManagerFactory factory = Persistence.createEntityManagerFactory("thePersistenceUnit");
            manager = factory.createEntityManager();
        }
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            PrintWriter out = response.getWriter();
            try {
                manager.getTransaction().begin();
                @SuppressWarnings("unchecked")
                List<Event> events = manager.createQuery("from Event").getResultList();
                Gson gson = new Gson();
                out.print(gson.toJson(events));
                manager.getTransaction().commit();
            } catch (Exception e) {
                manager.getTransaction().rollback();
            }
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String body = (String)request.getParameter("body");
            if (null != body) {
                try {
                    manager.getTransaction().begin();
                    Event event = new Event();
                    event.setBody(body);
                    manager.persist(event);
                    manager.getTransaction().commit();
                } catch (Exception e) {
                    manager.getTransaction().rollback();
                }
            } else {
                LOGGER.error("null body, cannot track");
            }
        }
    
    }
    

    的src /主/ JAVA /组织/我/跟踪器/ Event.java

    package org.my.tracker;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    
    @Entity
    public class Event {
        @Id
        @GeneratedValue
        private Integer id;
        private String body;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getBody() {
            return body;
        }
    
        public void setBody(String body) {
            this.body = body;
        }
    
    }
    

    好吧,多亏了所有这些强大的工具,这很简单,效果很好,除了我不能

    1. 了解如何通过属性设置我的数据库位置(是否只能通过tomcat server.xml调整(我不能因为它不属于我)或spring(这是一个相当弱的理由)在我的项目中只投入了一些属性注入...),

    2. (和3.)每次启动我的webapp时,我的数据库都是空的。当然,你会告诉我,因为我把&#34;创建&#34; persistence.xml中的值

          <property name="hibernate.hbm2ddl.auto" value="create"/>
      
    3. 好吧,我可以把

      • create-drop:与&#34; create&#34;相同的结果在我的情况下(这是预期的,因为&#34;掉落&#34;确实意味着与#34相反;保持一切处于关闭状态&#34;:D)
      • none:但是第一次未部署webapp时未创建数据库
      • 验证:我可以在webapp重新启动时恢复我的内容,但是没有,首先如果它不存在,则不会创建数据库架构和表,并且我的webapp无法使用它:)

      所以我希望尽可能保持事情的简单,是否可能?

      如果没有其他方法除了编写一个sql脚本来初始化我的数据库,只有它不存在,我将不胜感激,你提供代码或一些提示,因为我在这个领域是完全愚蠢的。

      修改

      因此,当我提出一条评论时,实际上,&#34;更新&#34;是我正在寻找的价值。 像魅力一样工作。

      我没有发现除弹簧之外的任何其他方式来传递变量而不是常量值。但是,嘿,这在这样的领域很常见:)(并且它的orm层也是春天)

1 个答案:

答案 0 :(得分:2)

JPA 2.1提供了用于创建架构的标准属性。寻找

javax.persistence.schema-generation.database.action

并设置为createdrop-and-create。类似地,存在用于在EMF启动时执行脚本的属性。任何兼容的JPA实现的文档都应该记录它们