仅当数据库,模式和表不存在时才自动创建它们 [英] How to auto-create database, schema and table only if they do not already exist

查看:131
本文介绍了仅当数据库,模式和表不存在时才自动创建它们的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个简单的网络应用程序

I want to create a simple webapp that

  • 允许远程客户端跟踪发布请求中的某些内容
  • 将所有跟踪保持在轻量级数据库中
  • 在获取请求时返回所有跟踪

关于数据库,我想

  1. 将其位置放入我的Web应用程序的属性文件中(并将此位置用于persistence.xml中设置的hibernate.location.url)
  2. 如果数据库和架构和表尚不存在,则使用它们创建数据库
  3. 使用现有的数据库和架构以及表和数据(如果存在)

所以我用以下方法创建了一个Maven项目:

So I created a maven project with:

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/main/resources/META-INF/persistence.xml

src/main/resources/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/main/webapp/WEB-INF/web.xml

src/main/webapp/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/main/java/org/my/tracker/EventServlet.java

src/main/java/org/my/tracker/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/main/java/org/my/tracker/Event.java

src/main/java/org/my/tracker/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;
    }

}

好吧,感谢所有这些强大的工具,它很简单并且运行得很好,除了我不能

Well, thanks to all these powerful tools, this is simple and works quite nicely, except that I could not

  1. 查看如何通过属性(只能通过tomcat server.xml调音(我不能为此做的事不属于我))或spring(这是一个很弱的原因)来设置数据库位置在我的项目中放入一些弹簧,仅用于1个属性注入...),

  1. see how to set my db location through a property (is it only possible through tomcat server.xml tune (that I cannot do for it does not belong to me) or spring (which is quite a weak reason to put some spring in my project only for 1 property injection...),

(和3.),每次启动Webapp时,我的数据库都是空的.当然,您会告诉我的,因为我在persistence.xml中放置了创建"值

(and 3.) each time I launch my webapp, my database is empty. Of course, you will tell me, since I put "create" value in persistence.xml

    <property name="hibernate.hbm2ddl.auto" value="create"/>

好吧,我可以说

  • create-drop:在我的情况下,结果与"create"相同(这是预料之中的,因为"drop"的含义与在关机时保持一切"的反义词很相似:D)
  • 无:但是第一次未部署Webapp时不会创建数据库
  • validate:好吧,我可以在webapp重新启动时恢复我的内容,但是没有,首先,如果它不存在,则不会创建数据库架构和表,并且我的webapp无法使用它:)

所以我想尽可能使事情像上面一样简单,有可能吗?

So I would like if possible to keep things as simple as they are above, is it possible ?

如果没有其他方法可以编写一个sql脚本来初始化我的数据库(只有当它不存在时),我将不胜感激,因为我是该领域的佼佼者,请提供代码或一些提示.

If there is no other way than writing an sql script to initialize my db only if it does not exist, I would appreciate you give the code or some hints, for I am a complete dumb in this field.

修改

因此,当我发表评论时,实际上,更新"是我想要的值. 像魅力一样工作.

So as I put in one comment, actually, "update" is the value I was looking for. Work like a charm.

除了spring以外,我没有其他方法可以传递变量而不是常量值.但是,嘿,无论如何在这种领域都是很常见的:)(并且也增加了它的orm层)

I did not find any other way than spring to pass variables instead of constant values. But hey that is quite common in such field anyway :) (and spring its orm layer too)

推荐答案

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

JPA 2.1 provides standard properties for creating schema. Look for

javax.persistence.schema-generation.database.action

并设置为createdrop-and-create.同样,有一些属性可以在启动EMF时执行脚本.任何符合要求的JPA实施的文档都应记录在文档中

and set to create or drop-and-create. Similarly there are properties for executing scripts at startup of an EMF. Docs for any compliant JPA implementation should document them

这篇关于仅当数据库,模式和表不存在时才自动创建它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆