我开始使用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运行.sql脚本?
你需要编写java代码来运行这些create table语句的任何特殊原因吗? 它们在某种程度上是动态的吗?
因为他想通过Java xD做所有事情
好。您可以在此项目中使用此类(由于文件长度而在pastebin上发布)。但请记住保留apache许可证信息。
JDBC ScriptRunner
这是删除了依赖项的iBatis ScriptRunner的ripoff。
你可以像这样使用它
Connection con = ....
ScriptRunner runner = new ScriptRunner(con, [booleanAutoCommit], [booleanStopOnerror]);
runner.runScript(new BufferedReader(new FileReader("test.sql")));
而已!
非常少数的课程。我必须补充说,130行会引起头痛。我将其替换为"String trimmedLine = line.trim()。replaceAll("; $",Matcher.quoteReplacement(";"));"因为你可能会得到stackoverflow.com/questions/3499483/
这可以用于返回ResultSet,还是只适用于更新语句?我尝试使用它,但无法弄清楚如何让它返回ResultSet。我会选择Spring但是使用类比使用整个库更容易。
小心链接到脚本 - 如果你的脚本有一个代码"注释",如select 1; -- do nothing那么脚本不会执行它,但将其视为较长命令的前半部分[与新命令连接]另一个副作用 - 如果这是你文件中的最后一件事,它根本不会运行它。如果您只是坚持使用单行sql注释,那就没关系
这个班级无法处理PROCEDURE
在创建使用DELIMITER和END的过程时不起作用
我冒昧地复制代码,更新它以添加对存储过程的分隔符的支持,将其上传到GitHub,并在@jitter的答案中更新链接。
我对此做了很多研究,并从春天找到了一个好的工具。我认为使用SimpleJdbcTestUtils.executeSqlScript(...)实际上是最好的解决方案,因为它更加维护和测试。
编辑:SimpleJdbcTestUtils已弃用。你应该使用JdbcTestUtils。更新了链接。
谢谢@Amir Raminfar,你的回答帮助了我。无论如何,作为更新,spring已弃用SimpleJdbcTestUtil并建议将来使用JdbcTestUtils。
这是最好的答案,Spring框架团队很活跃。
从Spring 4.0.3开始。 JdbcTestUtils.executeSqlScript()方法现已弃用。应该使用ScriptUtils.executeSqlScript(...)代替。
请注意,无论是否积极开发,这些实用程序类的设计都考虑了测试,并且对于大多数情况来说是不够的;例如,由于分隔符问题,它们不允许您创建存储过程;根据您的需要,joe776的答案可能是更好的选择,
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();
}
到目前为止这里是最好的答案。我厌倦了看到答案,告诉你从命令行运行MySQL转储导入。在数据库位于不同服务器上的自动化环境中不能很好地工作。
@Zoidberg mysql命令行客户端和mysqldump在网络上正常工作,可以在自动脚本中使用。将数据库放在不同的服务器上应该没有问题。
@Asaph你是对的。我实际上尝试了上述解决方案,发现性能非常慢。我使用命令行参数就好了,所以我上面的评论实际上是不正确的。
对于由';'拆分的简单sql脚本你可以使用这个简单的功能。
它逐个删除注释和运行语句
static void executeScript(Connection conn, InputStream in)
throws SQLException
{
Scanner s = new Scanner(in);
s.useDelimiter("/\\*[\\s\\S]*?\\*/|--[^\
\
]*|;");
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();
}
}
您假设注释不能出现在单个语句中。在CREATE TABLE中,这很常见。
我会说更多。它不支持复杂查询,但您可以将分隔符更改为其他内容,例如'; [ s r n] * \'。并根据需要使用评论。
对不起,但这个工作更好stackoverflow.com/questions/1497569/
Atais,很高兴看到你的尝试...我的代码只是一个例子,使用它你希望:)
@Pantelis Sopasakis
在GitHub上稍微修改过的版本:https://gist.github.com/831762/
它更容易跟踪修改。
你能用这个:
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+"
");
c.prepareCall(sql).execute(sql);
}
此函数获取SQL文件和数据库连接。
然后它使用java.io中的BufferedReader逐行读取文件。
最后,执行read语句。
Java 8+版本:
public static void executeSQL(Path p, Connection c) throws Exception {
List lines = Files.readAllLines(p);
String s = String.join("
", lines.toArray(new String[0]));
c.prepareCall(s).execute(s);
}
虽然此代码可以回答这个问题,但提供有关如何和/或解决问题的原因的其他背景将提高答案的长期价值。请阅读这个如何回答提供高质量的答案。
另一个有趣的选择是使用Jisql来运行脚本。由于源代码可用,因此应该可以将其嵌入到应用程序中。
编辑:仔细看看;将其嵌入其他内容需要对其源代码进行一些修改。
关于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语句文件或文件列表
的SqlCommand
srcFiles
3.fileset配置
对于Oracle PL / SQL,Oracle JDBC驱动程序确实支持执行整个SQL脚本,包括存储过程和匿名块(PL / SQL特定表示法),请参阅
JDBC驱动程序可以访问PL / SQL存储过程吗?
Oracle JDBC驱动程序常见问题解答有更多信息:
Oracle JDBC drivers support execution
of PL/SQL stored procedures and
anonymous blocks. They support both
SQL92 escape syntax and Oracle PL/SQL
block syntax. The following PL/SQL
calls would work with any Oracle JDBC
driver:
// 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()方法。
这个问题的第一个链接被打破了。
编写代码:
读入包含许多SQL语句的文件。
运行每个SQL语句。
如果我这样做,我应该解析.sql文件。我期待有一个我无法找到的jdbc功能。
没有办法做到这一点。
您可以通过Runtime.exec(String [])运行mysql命令行客户端,并在决定使用此选项时阅读本文
或者尝试使用ibatis的ScriptRunner(com.ibatis.common.jdbc.ScriptRunner)。但是,为了运行脚本而包含整个库有点愚蠢。
对,是真的。添加一个lib只是为了运行一个脚本没有意义:(我认为jdbc没有这样的东西是很奇怪的。