Skip to content

Commit 88e7958

Browse files
authored
[BAEL-8517] Multiple SQL statements as one in JDBC (#18160)
* Initial commit for BAEL-8803 * Remove service test * Initial commit * Review 1 updates * Update to Live test * Review comments * Review comments * AssertJ
1 parent 4411147 commit 88e7958

File tree

3 files changed

+203
-0
lines changed

3 files changed

+203
-0
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.baeldung.sql;
2+
3+
import java.sql.CallableStatement;
4+
import java.sql.Connection;
5+
import java.sql.ResultSet;
6+
import java.sql.SQLException;
7+
import java.sql.Statement;
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
11+
public class MultipleSQLExecution {
12+
13+
private Connection connection;
14+
15+
public MultipleSQLExecution(Connection connection) {
16+
this.connection = connection;
17+
}
18+
19+
public boolean executeMultipleStatements() throws SQLException {
20+
String sql = "INSERT INTO users (name, email) VALUES ('Alice', '[email protected]');" +
21+
"INSERT INTO users (name, email) VALUES ('Bob', '[email protected]');";
22+
23+
try (Statement statement = connection.createStatement()) {
24+
statement.execute(sql);
25+
return true;
26+
}
27+
}
28+
29+
public int[] executeBatchProcessing() throws SQLException {
30+
try (Statement statement = connection.createStatement()) {
31+
connection.setAutoCommit(false);
32+
33+
statement.addBatch("INSERT INTO users (name, email) VALUES ('Charlie', '[email protected]')");
34+
statement.addBatch("INSERT INTO users (name, email) VALUES ('Diana', '[email protected]')");
35+
36+
int[] updateCounts = statement.executeBatch();
37+
connection.commit();
38+
39+
return updateCounts;
40+
}
41+
}
42+
43+
public boolean callStoredProcedure() throws SQLException {
44+
try (CallableStatement callableStatement = connection.prepareCall("{CALL InsertMultipleUsers()}")) {
45+
callableStatement.execute();
46+
return true;
47+
}
48+
}
49+
50+
public List<User> executeMultipleSelectStatements() throws SQLException {
51+
String sql = "SELECT * FROM users WHERE email = '[email protected]';" +
52+
"SELECT * FROM users WHERE email = '[email protected]';";
53+
54+
List<User> users = new ArrayList<>();
55+
56+
try (Statement statement = connection.createStatement()) {
57+
statement.execute(sql); // Here we execute the multiple queries
58+
59+
do {
60+
try (ResultSet resultSet = statement.getResultSet()) {
61+
while (resultSet != null && resultSet.next()) {
62+
int id = resultSet.getInt("id");
63+
String name = resultSet.getString("name");
64+
String email = resultSet.getString("email");
65+
users.add(new User(id, name, email));
66+
}
67+
}
68+
} while (statement.getMoreResults());
69+
70+
}
71+
return users;
72+
}
73+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.baeldung.sql;
2+
3+
public class User {
4+
private int id;
5+
private String name;
6+
private String email;
7+
8+
public User(int id, String name, String email) {
9+
this.id = id;
10+
this.name = name;
11+
this.email = email;
12+
}
13+
14+
public int getId() {
15+
return id;
16+
}
17+
18+
public void setId(int id) {
19+
this.id = id;
20+
}
21+
22+
public String getName() {
23+
return name;
24+
}
25+
26+
public void setName(String name) {
27+
this.name = name;
28+
}
29+
30+
public String getEmail() {
31+
return email;
32+
}
33+
34+
public void setEmail(String email) {
35+
this.email = email;
36+
}
37+
}
38+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package com.baeldung.sql;
2+
3+
import org.junit.Before;
4+
import org.junit.jupiter.api.Test;
5+
6+
import java.sql.Connection;
7+
import java.sql.DriverManager;
8+
import java.sql.ResultSet;
9+
import java.sql.SQLException;
10+
import java.sql.Statement;
11+
import java.util.List;
12+
13+
import static org.junit.jupiter.api.Assertions.assertEquals;
14+
import static org.junit.jupiter.api.Assertions.assertTrue;
15+
import static org.assertj.core.api.Assertions.assertThat;
16+
17+
// Please note, this test requires a MySQL server running on localhost:3306 with database users_db already created.
18+
// We have added creation of the table it in the setup() method.
19+
public class MultipleSQLExecutionLiveTest {
20+
21+
private static Connection connection;
22+
23+
@Before
24+
public void setup() throws ClassNotFoundException, SQLException {
25+
Class.forName("com.mysql.cj.jdbc.Driver");
26+
String url = "jdbc:mysql://localhost:3306/user_db?allowMultiQueries=true";
27+
String username = "username";
28+
String password = "password";
29+
connection = DriverManager.getConnection(url, username, password);
30+
31+
Statement statement = connection.createStatement();
32+
String createUsersSql = "CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL, email VARCHAR(100) NOT NULL UNIQUE );";
33+
statement.execute(createUsersSql);
34+
}
35+
36+
@Test
37+
public void givenMultipleStatements_whenExecuting_thenRecordsAreInserted() throws SQLException {
38+
MultipleSQLExecution execution = new MultipleSQLExecution(connection);
39+
boolean result = execution.executeMultipleStatements();
40+
assertTrue(result, "The statements should execute successfully.");
41+
42+
try (Statement statement = connection.createStatement();
43+
ResultSet resultSet = statement.executeQuery("SELECT COUNT(*) AS count FROM users WHERE name IN ('Alice', 'Bob')")) {
44+
resultSet.next();
45+
int count = resultSet.getInt("count");
46+
assertEquals(2, count, "Two records should have been inserted.");
47+
}
48+
}
49+
50+
@Test
51+
public void givenBatchProcessing_whenExecuting_thenRecordsAreInserted() throws SQLException {
52+
MultipleSQLExecution execution = new MultipleSQLExecution(connection);
53+
int[] updateCounts = execution.executeBatchProcessing();
54+
assertEquals(2, updateCounts.length, "Batch processing should execute two statements.");
55+
56+
try (Statement statement = connection.createStatement();
57+
ResultSet resultSet = statement.executeQuery("SELECT COUNT(*) AS count FROM users WHERE name IN ('Charlie', 'Diana')")) {
58+
resultSet.next();
59+
int count = resultSet.getInt("count");
60+
assertEquals(2, count, "Two records should have been inserted via batch.");
61+
}
62+
}
63+
64+
@Test
65+
public void givenStoredProcedure_whenCalling_thenRecordsAreInserted() throws SQLException {
66+
MultipleSQLExecution execution = new MultipleSQLExecution(connection);
67+
boolean result = execution.callStoredProcedure();
68+
assertTrue(result, "The stored procedure should execute successfully.");
69+
70+
try (Statement statement = connection.createStatement();
71+
ResultSet resultSet = statement.executeQuery("SELECT COUNT(*) AS count FROM users WHERE name IN ('Eve', 'Frank')")) {
72+
resultSet.next();
73+
int count = resultSet.getInt("count");
74+
assertEquals(2, count, "Stored procedure should have inserted two records.");
75+
}
76+
}
77+
78+
@Test
79+
public void givenMultipleSelectStatements_whenExecuting_thenCorrectUsersAreFetched() throws SQLException {
80+
MultipleSQLExecution execution = new MultipleSQLExecution(connection);
81+
execution.executeMultipleStatements();
82+
83+
List<User> users = execution.executeMultipleSelectStatements();
84+
85+
// Here we verify that exactly two users are fetched and their names match the expected ones
86+
assertThat(users)
87+
.hasSize(2)
88+
.extracting(User::getName)
89+
.containsExactlyInAnyOrder("Alice", "Bob");
90+
}
91+
}
92+

0 commit comments

Comments
 (0)