From 24d5ed259064e53ebaae05c2534e407643089ba2 Mon Sep 17 00:00:00 2001
From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com>
Date: Mon, 21 Aug 2023 19:23:25 +0530
Subject: [PATCH] Bael 6870 (#14582)
* BAEL-6801 (#4)
Validate string length with Java validation annotations
* Bael-6870, Executing SQL Script File in Java
* Bael-6870, Fixed formatting on pom.xml
* Bael-6870, Fixing Jenkins Build Failure
* Bael-6870, PR Review comments
* Bael-6870, PR Review comments
---
.../core-java-persistence-2/pom.xml | 12 +++
.../baeldung/script/MyBatisScriptUtility.java | 13 ++++
.../baeldung/script/SpringScriptUtility.java | 29 +++++++
.../script/SqlScriptBatchExecutor.java | 74 ++++++++++++++++++
.../script/MyBatisScriptUtilityUnitTest.java | 46 ++++++++++++
.../script/SpringScriptUtilityUnitTest.java | 47 ++++++++++++
.../SqlScriptBatchExecutorUnitTest.java | 47 ++++++++++++
.../src/test/resources/employee.sql | 75 +++++++++++++++++++
8 files changed, 343 insertions(+)
create mode 100644 persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/script/MyBatisScriptUtility.java
create mode 100644 persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/script/SpringScriptUtility.java
create mode 100644 persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/script/SqlScriptBatchExecutor.java
create mode 100644 persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/script/MyBatisScriptUtilityUnitTest.java
create mode 100644 persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/script/SpringScriptUtilityUnitTest.java
create mode 100644 persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/script/SqlScriptBatchExecutorUnitTest.java
create mode 100644 persistence-modules/core-java-persistence-2/src/test/resources/employee.sql
diff --git a/persistence-modules/core-java-persistence-2/pom.xml b/persistence-modules/core-java-persistence-2/pom.xml
index 0bec7a808f..2013bdb6af 100644
--- a/persistence-modules/core-java-persistence-2/pom.xml
+++ b/persistence-modules/core-java-persistence-2/pom.xml
@@ -70,6 +70,16 @@
${assertj.version}
test
+
+ org.mybatis
+ mybatis
+ ${mybatis.version}
+
+
+ org.springframework
+ spring-jdbc
+ ${spring-jdbc.version}
+
@@ -80,6 +90,8 @@
20220320
07.00.00-MS-GA
2.1.214
+ 5.3.29
+ 3.5.7
\ No newline at end of file
diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/script/MyBatisScriptUtility.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/script/MyBatisScriptUtility.java
new file mode 100644
index 0000000000..8a9bbb6e20
--- /dev/null
+++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/script/MyBatisScriptUtility.java
@@ -0,0 +1,13 @@
+package com.baeldung.script;
+
+import org.apache.ibatis.jdbc.ScriptRunner;
+import java.sql.Connection;
+
+public class MyBatisScriptUtility {
+ public static void runScript(String path, Connection connection) throws Exception {
+ ScriptRunner scriptRunner = new ScriptRunner(connection);
+ scriptRunner.setSendFullScript(false);
+ scriptRunner.setStopOnError(true);
+ scriptRunner.runScript(new java.io.FileReader(path));
+ }
+}
diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/script/SpringScriptUtility.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/script/SpringScriptUtility.java
new file mode 100644
index 0000000000..cf70dfa890
--- /dev/null
+++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/script/SpringScriptUtility.java
@@ -0,0 +1,29 @@
+package com.baeldung.script;
+
+import org.springframework.core.io.PathResource;
+import org.springframework.core.io.support.EncodedResource;
+import org.springframework.jdbc.datasource.init.ScriptUtils;
+
+import java.sql.Connection;
+
+public class SpringScriptUtility {
+ public static void runScript(String path, Connection connection) {
+ boolean continueOrError = false;
+ boolean ignoreFailedDrops = false;
+ String commentPrefix = "--";
+ String separator = ";";
+ String blockCommentStartDelimiter = "/*";
+ String blockCommentEndDelimiter = "*/";
+
+ ScriptUtils.executeSqlScript(
+ connection,
+ new EncodedResource(new PathResource(path)),
+ continueOrError,
+ ignoreFailedDrops,
+ commentPrefix,
+ separator,
+ blockCommentStartDelimiter,
+ blockCommentEndDelimiter
+ );
+ }
+}
diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/script/SqlScriptBatchExecutor.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/script/SqlScriptBatchExecutor.java
new file mode 100644
index 0000000000..b9da968abe
--- /dev/null
+++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/script/SqlScriptBatchExecutor.java
@@ -0,0 +1,74 @@
+package com.baeldung.script;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class SqlScriptBatchExecutor {
+ private static final Log logger = LogFactory.getLog(SqlScriptBatchExecutor.class);
+ private static final Pattern COMMENT_PATTERN = Pattern.compile("--.*|/\\*(.|[\\r\\n])*?\\*/");
+ public static void executeBatchedSQL(String scriptFilePath, Connection connection, int batchSize) throws Exception {
+ List sqlStatements = parseSQLScript(scriptFilePath);
+ executeSQLBatches(connection, sqlStatements, batchSize);
+ }
+ private static List parseSQLScript(String scriptFilePath) throws IOException {
+ List sqlStatements = new ArrayList<>();
+
+ try (BufferedReader reader = new BufferedReader(new FileReader(scriptFilePath))) {
+ StringBuilder currentStatement = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ Matcher commentMatcher = COMMENT_PATTERN.matcher(line);
+ line = commentMatcher.replaceAll("");
+ line = line.trim();
+
+ if (line.isEmpty()) {
+ continue;
+ }
+
+ currentStatement.append(line).append(" ");
+
+ if (line.endsWith(";")) {
+ sqlStatements.add(currentStatement.toString());
+ logger.info(currentStatement.toString());
+ currentStatement.setLength(0);
+ }
+ }
+ } catch (IOException e) {
+ throw e;
+ }
+ return sqlStatements;
+ }
+
+ private static void executeSQLBatches(Connection connection, List sqlStatements, int batchSize)
+ throws SQLException {
+ int count = 0;
+ Statement statement = connection.createStatement();
+
+ for (String sql : sqlStatements) {
+ statement.addBatch(sql);
+ count++;
+
+ if (count % batchSize == 0) {
+ logger.info("Executing batch");
+ statement.executeBatch();
+ statement.clearBatch();
+ }
+ }
+ // Execute any remaining statements
+ if (count % batchSize != 0) {
+ statement.executeBatch();
+ }
+ connection.commit();
+ }
+}
diff --git a/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/script/MyBatisScriptUtilityUnitTest.java b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/script/MyBatisScriptUtilityUnitTest.java
new file mode 100644
index 0000000000..98f82cfbd5
--- /dev/null
+++ b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/script/MyBatisScriptUtilityUnitTest.java
@@ -0,0 +1,46 @@
+package com.baeldung.script;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.jupiter.api.AfterAll;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+public class MyBatisScriptUtilityUnitTest {
+ private static final Log logger = LogFactory.getLog(MyBatisScriptUtilityUnitTest.class);
+ private static Connection connection = null;
+ private static final String JDBC_URL = "jdbc:h2:mem:testdb1";
+ private static final String USERNAME = "user";
+ private static final String PASSWORD = "password";
+
+ @Before
+ public void prepareConnection() throws Exception {
+ connection = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD);
+ }
+
+ @AfterAll
+ public static void closeConnection() throws Exception {
+ connection.close();
+ }
+
+ @Test
+ public void givenConnectionObject_whenSQLFile_thenExecute() throws Exception {
+ String path = new File(ClassLoader.getSystemClassLoader()
+ .getResource("employee.sql").getFile()).toPath().toString();
+ MyBatisScriptUtility.runScript(path, connection);
+
+ Statement statement = connection.createStatement();
+ ResultSet resultSet = statement.executeQuery("SELECT COUNT(1) FROM employees");
+ if (resultSet.next()) {
+ int count = resultSet.getInt(1);
+ Assert.assertEquals("Incorrect number of records inserted", 20, count);
+ }
+ }
+}
diff --git a/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/script/SpringScriptUtilityUnitTest.java b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/script/SpringScriptUtilityUnitTest.java
new file mode 100644
index 0000000000..be6e39ca31
--- /dev/null
+++ b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/script/SpringScriptUtilityUnitTest.java
@@ -0,0 +1,47 @@
+package com.baeldung.script;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.jupiter.api.AfterAll;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+public class SpringScriptUtilityUnitTest {
+ private static final Log logger = LogFactory.getLog(SpringScriptUtilityUnitTest.class);
+
+ private static Connection connection = null;
+ private static final String JDBC_URL = "jdbc:h2:mem:testdb2";
+ private static final String USERNAME = "user";
+ private static final String PASSWORD = "password";
+
+ @Before
+ public void prepareConnection() throws Exception {
+ connection = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD);
+ }
+
+ @AfterAll
+ public static void closeConnection() throws Exception {
+ connection.close();
+ }
+
+ @Test
+ public void givenConnectionObject_whenSQLFile_thenExecute() throws Exception {
+ String path = new File(ClassLoader.getSystemClassLoader()
+ .getResource("employee.sql").getFile()).toPath().toString();
+ SpringScriptUtility.runScript(path, connection);
+
+ Statement statement = connection.createStatement();
+ ResultSet resultSet = statement.executeQuery("SELECT COUNT(1) FROM employees");
+ if (resultSet.next()) {
+ int count = resultSet.getInt(1);
+ Assert.assertEquals("Incorrect number of records inserted", 20, count);
+ }
+ }
+}
diff --git a/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/script/SqlScriptBatchExecutorUnitTest.java b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/script/SqlScriptBatchExecutorUnitTest.java
new file mode 100644
index 0000000000..3b1210fd00
--- /dev/null
+++ b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/script/SqlScriptBatchExecutorUnitTest.java
@@ -0,0 +1,47 @@
+package com.baeldung.script;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.jupiter.api.AfterAll;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+public class SqlScriptBatchExecutorUnitTest {
+ private static final Log logger = LogFactory.getLog(SqlScriptBatchExecutorUnitTest.class);
+ private static Connection connection = null;
+ private static final String JDBC_URL = "jdbc:h2:mem:testdb3";
+ private static final String USERNAME = "user";
+ private static final String PASSWORD = "password";
+
+ @Before
+ public void prepareConnection() throws Exception {
+ connection = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD);
+ }
+
+ @AfterAll
+ public static void closeConnection() throws Exception {
+ connection.close();
+ }
+
+ @Test
+ public void givenConnectionObject_whenSQLFile_thenExecute() throws Exception {
+ String path = new File(ClassLoader.getSystemClassLoader()
+ .getResource("employee.sql").getFile()).toPath().toString();
+ SqlScriptBatchExecutor.executeBatchedSQL(path, connection, 10);
+ Statement statement = connection.createStatement();
+ ResultSet resultSet = statement.executeQuery("SELECT COUNT(1) FROM employees");
+
+ if (resultSet.next()) {
+ int count = resultSet.getInt(1);
+ Assert.assertEquals("Incorrect number of records inserted", 20, count);
+ }
+ }
+
+}
diff --git a/persistence-modules/core-java-persistence-2/src/test/resources/employee.sql b/persistence-modules/core-java-persistence-2/src/test/resources/employee.sql
new file mode 100644
index 0000000000..c532458163
--- /dev/null
+++ b/persistence-modules/core-java-persistence-2/src/test/resources/employee.sql
@@ -0,0 +1,75 @@
+/**
+Script Name : Create employees script
+Author: Parthiv Pradhan
+
+**/
+
+-- Create the employees table if it doesn't exist
+CREATE TABLE employees (
+ id INT PRIMARY KEY,
+ first_name VARCHAR(50),
+ last_name VARCHAR(50),
+ department VARCHAR(50),
+ salary DECIMAL(10, 2)
+);
+
+-- Insert employee records
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (1, 'John', 'Doe', 'HR', 50000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (2, 'Jane', 'Smith', 'IT', 60000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (3, 'Michael', 'Johnson', 'Finance', 55000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (4, 'Emily', 'Williams', 'Marketing', 52000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (5, 'David', 'Brown', 'IT', 65000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (6, 'Sarah', 'Miller', 'Finance', 58000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (7, 'Robert', 'Jones', 'HR', 53000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (8, 'Jessica', 'Davis', 'Marketing', 51000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (9, 'William', 'Wilson', 'IT', 59000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (10, 'Jennifer', 'Taylor', 'Finance', 57000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (11, 'Daniel', 'Anderson', 'Marketing', 54000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (12, 'Linda', 'Martinez', 'HR', 52000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (13, 'Christopher', 'Lopez', 'IT', 62000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (14, 'Karen', 'Hernandez', 'Finance', 56000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (15, 'Mark', 'Garcia', 'Marketing', 53000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (16, 'Patricia', 'Lee', 'HR', 51000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (17, 'Anthony', 'Clark', 'IT', 60000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (18, 'Maria', 'Lewis', 'Finance', 59000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (19, 'Paul', 'Walker', 'Marketing', 55000.00);
+
+INSERT INTO employees (id, first_name, last_name, department, salary)
+VALUES (20, 'Ruth', 'Young', 'HR', 54000.00);