如何将Spring中的HSQLDB嵌入到WebApp中

时间:2009-09-04 18:41:11

标签: java spring web-applications hsqldb

我有一个带有Spring的webApp,当我在服务器模式下使用HSQLDB时它可以正常工作,但在文件模式下,它只通过了单元测试。这是我的数据来源:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="org.hsqldb.jdbcDriver" />

     <property name="url" value="jdbc:hsqldb:hsql://localhost/images" />
    <property name="username" value="sa" />
    <property name="password" value="" />
</bean>

我只是改变了这一行

   <property name="url" value="jdbc:hsqldb:hsql://localhost/images" />    
   ( -- Server mode)

这个

     <property name="url" value="jdbc:hsqldb:file:data/images" />      
     (-- In file)

它只是通过单元测试,并在网络应用程序中失败。

我认为在文件模式下,当我运行webapp时,HSQLDB找不到数据库的文件。

我已经尝试将数据库的数据放在webapp的根目录和web-inf内部,但它不起作用。

3 个答案:

答案 0 :(得分:2)

好吧,如果你把数据库放在jar里面这样:

<property name="url" value="jdbc:hsqldb:res:/data/images" />

如果您尝试插入或修改数据库,则只能将其用作只读。

一种解决方案是将一个监听器放在web.xml中,这样当应用程序启动时,它将使用应用程序Web的根路径进行初始化。

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>maf</display-name>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>


     <!--This is to get root of the aplication-->

    <listener>
        <listener-class>
   org.atoms.HsqlDatabaseListener
        </listener-class>
    </listener>


       <!--Este listener se encarga de inicializar todo el contenedor de Spring y mantener una variable en el
  ServletContext que apunta a dicho contenedor -->

    <listener>
        <listener-class>
   org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>




</web-app>

听众:

package org.atoms;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;


/**
 *
 * @author atomsfat
 */
public class HsqlDatabaseListener implements ServletContextListener {

    private ServletContext context = null;

    public void contextInitialized(ServletContextEvent event) {
        context = event.getServletContext();

        String prefix = event.getServletContext().getRealPath("/");

        System.out.println("database root " + prefix);
        com.atoms.HsqlDatabasePathResolver.getInstance(prefix);


    }

    public void contextDestroyed(ServletContextEvent event) {
        context = event.getServletContext();

    }

另一堂课:

package com.atoms;


/**
 *
 * @author atomsfat
 */
public class HsqlDatabasePathResolver {


    private static HsqlDatabasePathResolver instance ;
    private static String applicationPath = "";

    private HsqlDatabasePathResolver() {
    }

      /** Get Instance.
   */
    static public synchronized HsqlDatabasePathResolver getInstance(String applicationPath) {

        if (instance == null) {

            HsqlDatabasePathResolver.applicationPath =
                    HsqlDatabasePathResolver.normalizePath(applicationPath);
            instance = new HsqlDatabasePathResolver();



            System.out.println("Inizalizando path : " + HsqlDatabasePathResolver.applicationPath);

        }
        return instance;
    }

    public  String getApplicationPath() {
        return applicationPath;
    }



      public  String getUrlDatabase(String urlDatabase) {


         return HsqlDatabasePathResolver.replaceAll(urlDatabase,"{apppath}", applicationPath);
    }


      /**

         *
         * replace the "\" character by "/" and remove relative paths
         *
         * @param path
         * @return
         */
        public static String normalizePath(String path) {
            if (path == null) {
                return null;
            }
            String normalized = path;
            if (normalized.equals("/.")) {
                return "/";
            }
            if (normalized.indexOf('\\') >= 0) {
                normalized = normalized.replace('\\', '/');
            }
            if (!normalized.startsWith("/") && normalized.indexOf(':') < 0) {
                normalized = "/" + normalized;
            }
            do {
                int index = normalized.indexOf("//");
                if (index < 0) {
                    break;
                }
                normalized = normalized.substring(0, index) + normalized.substring(index + 1);
            } while (true);
            do {
                int index = normalized.indexOf("/./");
                if (index < 0) {
                    break;
                }
                normalized = normalized.substring(0, index) + normalized.substring(index + 2);
            } while (true);
            do {
                int index = normalized.indexOf("/../");
                if (index >= 0) {
                    if (index == 0) {
                        return null;
                    }
                    int index2 = normalized.lastIndexOf('/', index - 1);
                    normalized = normalized.substring(0, index2) + normalized.substring(index + 3);
                } else {
                    return normalized;
                }
            } while (true);
        }




        public static String replaceAll(String str, String match, String replace) {
            if (match == null || match.length() == 0) {
                return str;
            }
            if (replace == null) {
                replace = "";
            }
            if(match.equals(replace))return str;
            StringBuffer ret=new StringBuffer();
            int i = str.indexOf(match);
            int y = 0;
            while (i >= 0)
            {
                //System.out.println("i:"+i+" y:"+y);
                ret.append(str.substring(y, i));
                ret.append(replace);
                //str = str.substring(y, i) + replace + str.substring(i + match.length());
                y = i + match.length();
                i = str.indexOf(match,y);
            }
            ret.append(str.substring(y));
            return ret.toString();
        }



}

这是我在春天使用的配置:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
     xmlns:jee="http://www.springframework.org/schema/jee"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-2.5.xsd
               http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">

     <!-- La definición del Datasource -->
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" lazy-init="true"
      destroy-method="close">
            <property name="driverClassName" value="org.hsqldb.jdbcDriver" />

          <property name="url">
               <ref bean="dataBaseUrl"/>
           </property>

            <property name="username" value="sa" />
            <property name="password" value="" />
        </bean>

     <!-- La definición del Factory de Session con Anotaciones -->
        <bean id="sessionFactory"
      class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" lazy-init="false">
            <property name="dataSource" ref="dataSource" />
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">
         org.hibernate.dialect.HSQLDialect
                    </prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="hibernate.format_sql">true</prop>
                </props>
            </property>
            <property name="mappingResources">
                <list>
                    <value>Atoms.hbm.xml</value>
                </list>

            </property>
        </bean>
     <!--HibernaTemplate-->
        <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
            <property name="sessionFactory">
                <ref bean="sessionFactory" />
            </property>
        </bean>
     <!-- Definición de los DAO`s -->

        <bean id="ipBlancaDao" class="org.atoms.impl.AtomsDaoHibernateImpl">
            <property name="hibernateTemplate" ref="hibernateTemplate" />
        </bean>


        <!--If your are not running in Web this will initialize with the directory from    the  process was started note that this classes is a singleton so if you are running in web the listener already have initialize the class with the path of the class-->


        <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>


     <bean id="hsqlDatabasePathResolver" class="com.atoms.HsqlDatabasePathResolver" factory-method="getInstance" lazy-init="false">
            <constructor-arg>
                <value>${user.dir}</value>
            </constructor-arg>
        </bean>

   <!--This bean just replace {apppath} whit the absolute path-->

        <bean id="dataBaseUrl" class="java.lang.String" factory-bean="hsqlDatabasePathResolver" lazy-init="false"
                      factory-method="getUrlDatabase">
            <constructor-arg>
                <value>jdbc:hsqldb:mem:{apppath}/WEB-INF/data/maf</value>
            </constructor-arg>

        </bean>  
    </beans>

是的,这项工作很糟糕,我认为解决方案是听众,有了它,你可以获得appWeb的路径。如果有人可以这么简单,请发表答案。

答案 1 :(得分:1)

我在这里找到了答案:

http://coding.derkeiler.com/Archive/Java/comp.lang.java.databases/2003-11/0096.html

我将de数据放在我的项目persistenceLayerWithData.jar的jar中。

然后我将此属性设置为数据源:

<property name="url" value="jdbc:hsqldb:res:/data/images" />

我将jar添加到web-inf / lib并进行战争(所有这些都使用maven)并在tomcat中部署并且它可以工作,我也将它部署在websphere 7中并且也可以工作。

但是当我运行whit mvn jetty时:运行它并不是我认为在运行jetty whit maven时它不会将jar放入claspath。

答案 2 :(得分:0)

您应该使用绝对文件路径。运行Web应用程序时,“当前”(或“工作”)目录很可能是应用程序服务器的bin文件夹。因此,当您为HSQLDB URL指定相对路径时,它会尝试从该处加载此文件,而不是相对于您的webapp根目录。