如何用Java执行SQL脚本文件?
我想在 Java 中执行 SQL 脚本文件,而不将整个文件内容读取到一个大查询中并执行它。
还有其他标准方法吗?
I want to execute an SQL script file in Java without reading the entire file content into a big query and executing it.
Is there any other standard way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
只要您不介意依赖 Ant,就有一种很好的方法可以从 Java 执行 SQL 脚本,而无需亲自阅读它们。在我看来,这种依赖在你的情况下是非常合理的。下面是示例代码,其中 SQLExec 类位于 ant.jar 中:
There is great way of executing SQL scripts from Java without reading them yourself as long as you don't mind having a dependency on Ant. In my opinion such a dependency is very well justified in your case. Here is sample code, where SQLExec class lives in ant.jar:
没有可移植的方法可以做到这一点。您可以将本机客户端作为外部程序执行来执行此操作:
There is no portable way of doing that. You can execute a native client as an external program to do that though:
Flyway 库对此非常有用:
它会扫描脚本的位置并按顺序运行它们。脚本可以使用 V01__name.sql 进行版本控制,因此如果仅调用 migrate,则只会运行那些尚未运行的脚本。使用名为“schema_version”的表来跟踪事物。但也可以做其他事情,请参阅文档:flyway。
clean 调用不是必需的,但对于从干净的数据库开始很有用。
另外,请注意位置(默认为“classpath:db/migration”),“:”后面没有空格,这让我很困惑。
Flyway library is really good for this:
This scans the locations for scripts and runs them in order. Scripts can be versioned with V01__name.sql so if just the migrate is called then only those not already run will be run. Uses a table called 'schema_version' to keep track of things. But can do other things too, see the docs: flyway.
The clean call isn't required, but useful to start from a clean DB.
Also, be aware of the location (default is "classpath:db/migration"), there is no space after the ':', that one caught me out.
不,您必须读取该文件,将其拆分为单独的查询,然后单独执行它们(或使用 JDBC 的批处理 API)。
原因之一是每个数据库都定义了自己的分隔 SQL 语句的方式(有些使用
;
,其他使用/
,有些允许两者,甚至定义您自己的分隔符)。No, you must read the file, split it into separate queries and then execute them individually (or using the batch API of JDBC).
One of the reasons is that every database defines their own way to separate SQL statements (some use
;
, others/
, some allow both or even to define your own separator).您不能使用 JDBC,因为它不支持 .解决方法是包含 iBatis iBATIS 是一个持久性框架,并调用
Scriptrunner
构造函数,如 iBatis 文档 。包含像 ibatis 这样的重量级持久性框架来运行简单的 sql 脚本并不好,而您可以使用命令行来执行此操作
You cannot do using JDBC as it does not support . Work around would be including iBatis iBATIS is a persistence framework and call the
Scriptrunner
constructor as shown in iBatis documentation .Its not good to include a heavy weight persistence framework like ibatis in order to run a simple sql scripts any ways which you can do using command line
由于 JDBC 不支持此选项,解决此问题的最佳方法是通过 Java 程序执行命令行。下面是 postgresql 的一个例子:
Since JDBC doesn't support this option the best way to solve this question is executing command lines via the Java Program. Bellow is an example to postgresql:
Apache iBatis 解决方案非常有效。
我使用的脚本示例正是我从 MySql 工作台运行的脚本。
这里有一篇带有示例的文章:
https://www.tutorialspoint.com/how-to-run -sql-script-using-jdbc#:~:text=你%20can%20execute%20.,to%20pass%20a%20connection%20object.&text=注册%20%20MySQL%20JDBC%20Driver,method%20of %20%20DriverManager%20类。
这就是我所做的:
pom.xml 依赖
项 执行脚本的代码:
The Apache iBatis solution worked like a charm.
The script example I used was exactly the script I was running from MySql workbench.
There is an article with examples here:
https://www.tutorialspoint.com/how-to-run-sql-script-using-jdbc#:~:text=You%20can%20execute%20.,to%20pass%20a%20connection%20object.&text=Register%20the%20MySQL%20JDBC%20Driver,method%20of%20the%20DriverManager%20class.
This is what I did:
pom.xml dependency
Code to execute script:
对于我的简单项目,用户应该能够选择要执行的 SQL 文件。
由于我对其他答案不满意,并且无论如何我都在使用 Flyway,所以我仔细查看了 Flyway 代码。
DefaultSqlScriptExecutor
正在执行实际执行,因此我尝试弄清楚如何创建DefaultSqlScriptExecutor
的实例。基本上,以下代码片段加载一个
String
,将其拆分为单个语句并逐个执行。Flyway 还提供除
StringResource
之外的其他LoadableResource
,例如FileSystemResource
。但我没有仔细观察过它们。由于
DefaultSqlScriptExecutor
和其他类未由 Flyway 正式记录,请谨慎使用代码片段。For my simple project the user should be able to select SQL-files which get executed.
As I was not happy with the other answers and I am using Flyway anyway I took a closer look at the Flyway code.
DefaultSqlScriptExecutor
is doing the actual execution, so I tried to figure out how to create an instance ofDefaultSqlScriptExecutor
.Basically the following snippet loads a
String
splits it into the single statements and executes one by one.Flyway also provides other
LoadableResource
s thanStringResource
e.g.FileSystemResource
. But I have not taken a closer look at them.As
DefaultSqlScriptExecutor
and the other classes are not officially documented by Flyway use the code-snippet with care.我发现可移植的最简单的外部工具是 jisql - https://www.xigole .com/software/jisql/jisql.jsp 。
您可以将其运行为:
The simplest external tool that I found that is also portable is jisql - https://www.xigole.com/software/jisql/jisql.jsp .
You would run it as:
JDBC 不支持此选项(尽管特定的数据库驱动程序可能提供此选项)。
不管怎样,将所有文件内容加载到内存中应该不会有问题。
JDBC does not support this option (although a specific DB driver may offer this).
Anyway, there should not be a problem with loading all file contents into memory.
试试这个代码:
Try this code:
如果您使用Spring,则可以使用
DataSourceInitializer
:https: //docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/datasource/init/DataSourceInitializer.html
If you use Spring you can use
DataSourceInitializer
:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/datasource/init/DataSourceInitializer.html