0
因此,我有一個文件schema.sql
,其中包含數據庫的模式,我希望在部署應用程序時相應地創建表。(批處理)數據庫模式部署後的servlet上下文偵聽器
的ServletContextListener
看起來像這樣
/**
* This class doesn't really belong to the Ui package, but it does depend on
* servlet technology like all the other classes here, so I've just put it here for the moment.
*
* The class may be moved in the future
*
* When the application is deployed and started, this class connects to the database,
* checks if the environment is compatible, checks various other things like whether
* Core.User.HASH_ALGO or Core.User.STRING_ENCODING are supported (see Core.User for
* details).
*/
package Ui;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletContext;
import com.mysql.jdbc.Driver;
import java.sql.*;
import java.io.*;
import java.net.URL;
/**
* Web application lifecycle listener.
*/
public class AppContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext s = sce.getServletContext();
String db_uri = s.getInitParameter("DB_HOST");
String db_user = s.getInitParameter("DB_USERNAME");
String db_pass = s.getInitParameter("DB_PASSWORD");
try {
Connection connection = DriverManager.getConnection(db_uri, db_user, db_pass);
//TODO check if version is compatible ;-), set app as unusable if necessary
s.setAttribute("db", connection);
Statement st = null;
if(null != connection) {
st = connection.createStatement();
String schema = null;
try {
InputStream str = s.getResourceAsStream("/WEB-INF/sql/schema.sql");
schema = readStream(str);
}
catch(Exception e) {
//TODO set global application state as unusable, with a message
}
finally {
int i = st.executeUpdate(schema);
}
}
} catch(SQLException e) {
//TODO set global application state as unusable, with a message
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
//TODO disconnect from the DB
}
protected String readStream(InputStream stream) {
BufferedInputStream bis = new BufferedInputStream(stream);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
try {
int result = bis.read();
while(result != -1) {
byte b = (byte)result;
buf.write(b);
result = bis.read();
}
}
catch(IOException e) {
return null;
}
finally {
return buf.toString();
}
}
}
像這樣的模式:
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT=0;
START TRANSACTION;
SET time_zone = "+00:00";
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL,
`username` varchar(20) COLLATE utf8_bin DEFAULT NULL,
`password` varchar(40) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
COMMIT;
的錯誤是:
您的SQL語法錯誤;檢查與你的MySQL服務器版本相對應的手冊,在'SET AUTOCOMMIT = 0; START TRANSACTION;
所以它在我看來好像它不接受一個鏡頭中的多個命令。什麼是正確的方式來使它工作?使用一個單獨的schema.sql
勢在必行。
The tran? 'addBatch()'和'executeBatch()'不起作用:( – Flavius 2011-12-30 18:35:08
對不起。至於tran,我的意思是說,一旦你做了'START TRANSACTION',盡一切努力確保交易完成。在過去有一些問題留在一個公開的事務中,特別是在連接池環境中會做很不愉快的事情。 – 2011-12-30 20:46:11
謝謝。分裂思想雖然工作,但接受。 – Flavius 2011-12-30 22:23:11