[英]Spring JDBC cannot handle DECLARE statement when running SQL Script
[英]Running a .sql script using MySQL with JDBC
我开始使用 MySQL 和 JDBC。
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql:///x", "x", "x");
stmt = conn.createStatement();
stmt.execute( "CREATE TABLE amigos" +
"("+
"id int AUTO_INCREMENT not null,"+
"nombre char(20) not null,"+
"primary key(id)" +
")");
我要创建 3-4 个表,这看起来不太好。
有没有办法从 MySQL JDBC 运行 a.sql 脚本?
好。 您可以在此项目中使用此类(由于文件长度而在pastebin上发布)。 但请记住保留apache许可证信息。
这是删除了依赖项的iBatis ScriptRunner的ripoff。
你可以像这样使用它
Connection con = ....
ScriptRunner runner = new ScriptRunner(con, [booleanAutoCommit], [booleanStopOnerror]);
runner.runScript(new BufferedReader(new FileReader("test.sql")));
而已!
我对此做了很多研究,并从春天找到了一个好的工具。 我认为使用SimpleJdbcTestUtils.executeSqlScript(...)
实际上是最好的解决方案,因为它更加维护和测试。
编辑:不推荐使用SimpleJdbcTestUtils
。 您应该使用JdbcTestUtils
。 更新了链接。
Spring Framework的ResourceDatabasePopulator
可能有所帮助。 正如您所说的那样,您正在使用MySQL和JDBC,我们假设您已准备好支持MySQL的DataSource
实例。 此外,假设您的MySQL脚本文件是类路径可定位的。 假设您使用的是WAR布局,脚本文件位于目录src/main/webapp/resources/mysql-scripts/...
或src/test/resources/mysql-scripts/...
然后,您可以使用ResourceDatabasePopulator
执行如下所示的SQL脚本:
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import javax.sql.DataSource;
DataSource dataSource = getYourMySQLDriverBackedDataSource();
ResourceDatabasePopulator rdp = new ResourceDatabasePopulator();
rdp.addScript(new ClassPathResource(
"mysql-scripts/firstScript.sql"));
rdp.addScript(new ClassPathResource(
"mysql-scripts/secondScript.sql"));
try {
Connection connection = dataSource.getConnection();
rdp.populate(connection); // this starts the script execution, in the order as added
} catch (SQLException e) {
e.printStackTrace();
}
对于由';'拆分的简单sql脚本 你可以使用这个简单的功能。 它逐个删除注释和运行语句
static void executeScript(Connection conn, InputStream in)
throws SQLException
{
Scanner s = new Scanner(in);
s.useDelimiter("/\\*[\\s\\S]*?\\*/|--[^\\r\\n]*|;");
Statement st = null;
try
{
st = conn.createStatement();
while (s.hasNext())
{
String line = s.next().trim();
if (!line.isEmpty())
st.execute(line);
}
}
finally
{
if (st != null)
st.close();
}
}
你能用这个:
public static void executeSQL(File f, Connection c) throws Exception {
BufferedReader br = new BufferedReader(new FileReader(f));
String sql = "", line;
while ((line = br.readLine()) != null) sql += (line+"\n");
c.prepareCall(sql).execute(sql);
}
此函数获取SQL文件和数据库连接。 然后它使用java.io中的BufferedReader逐行读取文件。
最后,执行read语句。
Java 8+版本:
public static void executeSQL(Path p, Connection c) throws Exception {
List<String> lines = Files.readAllLines(p);
String s = String.join("\n", lines.toArray(new String[0]));
c.prepareCall(s).execute(s);
}
关于SQL脚本运行器(我也在使用),我注意到以下代码:
for (int i = 0; i < cols; i++) {
String value = rs.getString(i);
print(value + "\t");
}
但是,在方法getString(int)的API文档中,提到索引以1开头 ,因此应该变为:
for (int i = 1; i <= cols; i++) {
String value = rs.getString(i);
print(value + "\t");
}
其次,ScriptRunner的这种实现不支持SQL脚本中的DELIMITER语句,如果您需要编译TRIGGERS或PROCEDURES,这些语句很重要。 所以我创建了ScriptRunner的这个修改版本: http ://pastebin.com/ZrUcDjSx,我希望你会发现它很有用。
编写代码:
Maven SQL插件使用此插件通过执行SQL语句文件或文件列表
对于Oracle PL / SQL,Oracle JDBC驱动程序确实支持执行整个SQL脚本,包括存储过程和匿名块(PL / SQL特定表示法),请参阅
Oracle JDBC驱动程序常见问题解答有更多信息:
Oracle JDBC驱动程序支持PL / SQL存储过程和匿名块的执行。 它们支持SQL92转义语法和Oracle PL / SQL块语法。 以下PL / SQL调用适用于任何Oracle JDBC驱动程序:
// SQL92 syntax
CallableStatement cs1 = conn.prepareCall
( "{call proc (?,?)}" ) ; // stored proc
CallableStatement cs2 = conn.prepareCall
( "{? = call func (?,?)}" ) ; // stored func
// Oracle PL/SQL block syntax
CallableStatement cs3 = conn.prepareCall
( "begin proc (?,?); end;" ) ; // stored proc
CallableStatement cs4 = conn.prepareCall
( "begin ? := func(?,?); end;" ) ; // stored func
应该可以读入文件并将内容提供给prepareCall()方法。
这是一个对我有用的快速而肮脏的解决方案。
public void executeScript(File scriptFile) {
Connection connection = null;
try {
connection = DriverManager.getConnection(url, user, password);
if(scriptFile.exists()) {
var buffer = new StringBuilder();
var scanner = new Scanner(scriptFile);
while(scanner.hasNextLine()) {
var line = scanner.nextLine();
buffer.append(line);
// If we encounter a semicolon, then that's a complete statement, so run it.
if(line.endsWith(";")) {
String command = buffer.toString();
connection.createStatement().execute(command);
buffer = new StringBuilder();
} else { // Otherwise, just append a newline and keep scanning the file.
buffer.append("\n");
}
}
}
else System.err.println("File not found.");
} catch (SQLException e) {
e.printStackTrace();
} finally {
if(connection != null) connection.close();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.