当前位置: 代码迷 >> Web前端 >> 改建myoa例子,使用hsql代替mysql随webapp启动
  详细解决方案

改建myoa例子,使用hsql代替mysql随webapp启动

热度:392   发布时间:2012-09-22 21:54:54.0
改造myoa例子,使用hsql代替mysql随webapp启动

首先,感谢myoa的作者,为我们提供了这样一个学习ssh的例子程序。该例子请参考另一篇博文http://mimmy.iteye.com/admin/blogs/840621

?

由于我电脑上没有安装mysql,打算使用hsql来代替mysql,用hsql的好处是数据库可以随webapp一起启动,不用在启动应用前再手动启动数据库服务,很方便。


?一、修改sql语句

用myoa提供的mysql数据库脚本生成的sql语句不符合hsql规范,需要将其进行转化。

比如,创建表:

CREATE MEMORY TABLE ADDRESS(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,USERNAME VARCHAR(20) DEFAULT '' NOT NULL,NAME VARCHAR(50) DEFAULT '' NOT NULL,SEX VARCHAR(10),MOBILE VARCHAR(20),EMAIL VARCHAR(50),QQ VARCHAR(20),COMPANY VARCHAR(100),ADDRESS VARCHAR(100),POSTCODE VARCHAR(10))

插入一条记录:

INSERT INTO USER VALUES(1,'admin','admin','abc@163.com')?


初始数据库只需要.script和.properties文件就可以了,服务启动后自动生成.log等其他文件。


二、 加入jar

hsql需要提供hsqldb.jar,它又依赖javax.servlet.jar和commons-logging.jar两个包。

将这三个包复制到\WebRoot\WEB-INF\lib下面,然后刷新一下工程,就能自动导入到工程路径中了。


三、web.xml

修改web.xml,加入处理hsql服务启动监听

?

	<context-param> 
		<param-name>hsql.dbPath</param-name> 
		<param-value>E:\Source\test\myoa\db</param-value> 
	</context-param>
	<context-param>
		<param-name>hsql.dbName</param-name>
		<param-value>demo</param-value>
	</context-param>
	<context-param>
		<param-name>hsql.port</param-name>
		<param-value>9001</param-value>
	</context-param>
	<listener>
		<listener-class>
			com.demo.HsqlStartListener
		</listener-class>
	</listener>

?

HsqlStartListener.java

?

package com.demo;

import org.hsqldb.Server;

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

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

/**
 * 该类的职责是在WebApp启动时自动开启HSQL服务。
 * 依然使用Server方式,不受AppServer的影响。
 * @author kiki1120
 * @since 2010-12-14
 */
public class HsqlStartListener implements ServletContextListener {
	
	private String path;
	private String dbName;
	private int port = -1;

	/**
	 * Listener销毁方法,在Web应用终止的时候执行"shutdown"命令关闭数据库
	 */
	public void contextDestroyed(ServletContextEvent arg0) {
		// 这里就不用说了,自然是关闭数据库操作
		Connection conn = null;
		try {
			Class.forName("org.hsqldb.jdbcDriver");
			StringBuilder url = new StringBuilder();
			url.append("jdbc:hsqldb:hsql://");
			url.append("localhost");
			url.append(port == 9001 ? "" : ":" + port);
			url.append("/").append(dbName);
			conn = DriverManager.getConnection(url.toString(), "sa", "");   
			Statement stmt = conn.createStatement();
			stmt.executeUpdate("SHUTDOWN;");
		} catch (Exception e){
			e.printStackTrace();
		}
	}

	public void contextInitialized(ServletContextEvent sce) {
		path = sce.getServletContext().getInitParameter("hsql.dbPath");
		dbName = sce.getServletContext().getInitParameter("hsql.dbName");

		try { 
			port = Integer.parseInt(sce.getServletContext().getInitParameter("hsql.port"));
		}catch(Exception e){
			port = 9001;
		}
		
		if (dbName == null || dbName.equals("")){
			System.out.println("Cant’ get hsqldb.dbName from web.xml Context Param");
			return;   
		}
		
		File dbDir = new File(path);
		
		if (!dbDir.exists()) {
			// 判断目录是否存在
			if (!dbDir.mkdirs()) {
				// 如果不存在创建,如果创建失败直接返回
				System.out.println("Can not create DB Dir for Hsql:" + dbDir);
				return;
			}
		}
		
		// 以下代码是做数据库恢复的。我们把原始的数据库放在classpath下,当启动web的时候,检查目标
		// 数据库是否存在,如果不存在,就把原始数据库复制为指定的数据库
		
		if (!path.endsWith("/")){
			path = path + "/";
		}
		
		File scriptFile = new File(path + dbName + ".script");
		File propertiesFile = new File(path + dbName + ".properties");
		
		if (scriptFile.exists() && propertiesFile.exists()){
			// 判断数据文件是否存在
			startServer(path, dbName, port);
		} else{
			System.out.println("Connect failed:Connect Hsqldb error or database files not exits!");
		}
			
	}

	/**
	 * 启动Hsqldb服务的方法
	 * @param dbPath 数据库路径
	 * @param dbName 数据库名称
	 * @param port 所使用的端口号
	 */
	private void startServer(String path, String dbName, int port) {
		// 它可是hsqldb.jar里面的类啊
		Server server = new Server();
		server.setDatabaseName(0, dbName);
		server.setDatabasePath(0, path + dbName);
		
		if (port != -1){
			server.setPort(port);
		}
		
		server.setSilent(true);
		server.start();
		System.out.println("hsqldb started…");
		// 等待Server启动
		
		try {
			Thread.sleep(800);
		} catch (InterruptedException e){
			e.printStackTrace();
		} 
	}

}

?

四、配置数据源

修改applicationContext.xml

?

	<!--  配置数据源 -->
	<bean id="dataSource"
		class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName">
			<value>org.hsqldb.jdbcDriver</value>
		</property>
		<property name="url">
			<value>jdbc:hsqldb:hsql://localhost/demo</value>
		</property>
		<property name="username">
			<value>sa</value>
		</property>
		<property name="password">
			<value></value>
		</property>
	</bean>


	<!-- 配置Hibernate -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref local="dataSource" />
		</property>
		<property name="mappingResources">
			<list>
				<value>com/demo/hibernate/beans/User.hbm.xml</value>
				<value>com/demo/hibernate/beans/Address.hbm.xml</value>
				<value>com/demo/hibernate/beans/Schedule.hbm.xml</value>
				<value>com/demo/hibernate/beans/Worklog.hbm.xml</value>
				<value>com/demo/hibernate/beans/Sms.hbm.xml</value>
				<value>com/demo/hibernate/beans/Notice.hbm.xml</value>
				<value>com/demo/hibernate/beans/Meeting.hbm.xml</value>
			</list>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.HSQLDialect
				</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
			</props>
		</property>
	</bean>

?

现在启动tomcat看看吧。

?

另外,我在编译工程时发现了几个问题。

1、找不到junit.jar ,从eclipse中就能导进来;

2、有六个jsp出现红叉叉,打开检查,原来是form标签与table标签闭合顺序不一致,最好将form放到table的上层;?

3、导入junit.jar仍然不能编译出class文件的话,我这里编写了一个ant自动编译脚本,执行它就能解决问题。


build.xml

?

<?xml version="1.0" encoding="UTF-8"?>
<project name="myoa" default="compile">
	
	<property name="build.src" value="src" />
	<property name="build.webroot" value="WebRoot/WEB-INF" />
	<property name="build.output" value="${build.webroot}/classes" />
	
	<target name="compile">
		<javac encoding="utf-8" destdir="${build.output}" srcdir="${build.src}" 
			   includeantruntime="false" includes="**/*.java" debug="on">
            <classpath>
            	<fileset dir="${build.webroot}/lib">
            		<include name="*.jar"/>
            	</fileset>
			</classpath>
		</javac>
		<copy todir="${build.output}">
			<fileset dir="${build.src}">
				<include name="**/*.xml"/>
				<include name="**/*.properties"/>
			</fileset>
		</copy>
	</target>

</project>
1 楼 javer 2011-03-16  
试了下,在eclipse rcp下尝试加入hsqldb自启动,此方法不通;只得改用调cmd命令的方法,不知道其他人有什么高招没?
2 楼 f0rb 2011-07-14  
    public void contextInitialized(ServletContextEvent sce) {
        // 启动hsql数据库
        Server.main(new String[]{
                "-database.0", "E:\\ws_j2ee\\LoginApp\\db/czsdb",
                "-dbname.0", ALIAS,
                "-no_system_exit", "true"
        });
    }
  相关解决方案