Reputation: 3116
I'm trying to write a bit of code that reads a SQL file (multiple CREATE TABLE
statements separated by ;
) and executes all the statements.
In pure JDBC, I could write:
String sqlQuery = "CREATE TABLE A (...); CREATE TABLE B (...);"
java.sql.Connection connection = ...;
Statement statement = connection.createStatement();
statement.executeUpdate(sqlQuery);
statement.close();
and both (all) the statements got executed. When I tried to do the same in spring JdbcTemplate, only the first statement is executed though!
String sqlQuery = "CREATE TABLE A (...); CREATE TABLE B (...);"
org.springframework.jdbc.core.JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.execute(sqlQuery);
Is there a way to execute multiple statements? While googling I found only solutions like "split the sqlQuery by ;
manually" which of course is useless (it'd require much more parsing).
Upvotes: 30
Views: 48140
Reputation: 354
I was looking for a similar option for my project's case then I did stumble upon the following https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.html
The provided Stackoverflow example is really neat and simple, if you want the Spring to handle the boilerplate sql handling on your behalf https://stackoverflow.com/a/23036217/1958683
Upvotes: 0
Reputation: 111
try it
public void executeSqlScript(Connection connection,StringBuffer sql)throws SQLException{
try {
connection.setAutoCommit(false);//disable auto commit
ScriptUtils.executeSqlScript(connection, new ByteArrayResource(sql.toString().getBytes()));
connection.commit();//commit manually
} catch (SQLException e) {
connection.rollback();
}finally{
connection.close();
}
}
Upvotes: 11
Reputation: 2703
I've solved the issue this way:
public void createDefaultDB(DataSource dataSource) {
Resource resource = new ClassPathResource("CreateDefaultDB.sql");
ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(resource);
databasePopulator.execute(dataSource);
}
You can inject DataSource
as usual:
import javax.sql.DataSource;
//...
@Autowired
private DataSource dataSource;
Upvotes: 29
Reputation: 948
We can also achive through SQLExec. Below code is working for me.
import java.io.File;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.SQLExec;
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.executeSql("");
}
private void executeSql(String sqlFilePath) {
final class SqlExecuter extends SQLExec {
public SqlExecuter() {
Project project = new Project();
project.init();
setProject(project);
setTaskType("sql");
setTaskName("sql");
}
}
SqlExecuter executer = new SqlExecuter();
executer.setSrc(new File("test1.sql"));
executer.setDriver("org.postgresql.Driver");
executer.setPassword("postgres");
executer.setUserid("postgres");
executer.setUrl("jdbc:postgresql://localhost/test");
executer.execute();
}
}
Upvotes: 0
Reputation: 3638
Maybe Spring's ScriptUtils will be useful in your case. Especially executeSqlScript
methods.
Note that DEFAULT_STATEMENT_SEPARATOR
has a default value of ';'
(see Constant Field Values)
Upvotes: 27