Skip to content

Commit bd0c4b4

Browse files
ianbrandtsbrannen
authored andcommitted
Deprecate SimpleJdbcTestUtils in favor of JdbcTestUtils
Several static utility methods in SimpleJdbcTestUtils accept an instance of SimpleJdbcTemplate as an argument; however, SimpleJdbcTemplate has been deprecated since Spring 3.1 in favor of simply using JdbcTemplate which now also supports Java 5 language constructs such as var-args. Consequently, use of such methods from SimpleJdbcTestUtils results in deprecation warnings without an equivalent API to migrate to. This commit addresses this issue by migrating all existing methods in SimpleJdbcTestUtils to JdbcTestUtils. The migrated methods now accept an instance of JdbcTemplate as an argument, thereby avoiding the deprecation warnings but maintaining semantic compatibility with the functionality previous available in SimpleJdbcTestUtils. In addition, this commit also introduces two new methods: - countRowsInTableWhere(): counts the rows in a given table, using a provided `WHERE` clause - dropTables(): drops the tables with the specified names Issue: SPR-9235
1 parent 04bfc80 commit bd0c4b4

File tree

3 files changed

+229
-19
lines changed

3 files changed

+229
-19
lines changed

spring-test/src/main/java/org/springframework/test/jdbc/JdbcTestUtils.java

Lines changed: 224 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,27 +18,232 @@
1818

1919
import java.io.IOException;
2020
import java.io.LineNumberReader;
21+
import java.util.LinkedList;
2122
import java.util.List;
2223

24+
import org.apache.commons.logging.Log;
25+
import org.apache.commons.logging.LogFactory;
26+
27+
import org.springframework.core.io.Resource;
28+
import org.springframework.core.io.ResourceLoader;
29+
import org.springframework.core.io.support.EncodedResource;
30+
import org.springframework.dao.DataAccessException;
31+
import org.springframework.dao.DataAccessResourceFailureException;
32+
import org.springframework.jdbc.core.JdbcTemplate;
2333
import org.springframework.util.StringUtils;
2434

2535
/**
26-
* JdbcTestUtils is a collection of JDBC related utility methods for use in unit
27-
* and integration testing scenarios.
36+
* {@code JdbcTestUtils} is a collection of JDBC related utility functions
37+
* intended to simplify standard database testing scenarios.
2838
*
39+
* <p>As of Spring 3.2, {@code JdbcTestUtils} supersedes {@link SimpleJdbcTestUtils}.
40+
*
2941
* @author Thomas Risberg
42+
* @author Sam Brannen
43+
* @author Juergen Hoeller
3044
* @since 2.5.4
3145
*/
3246
public class JdbcTestUtils {
3347

48+
private static final Log logger = LogFactory.getLog(JdbcTestUtils.class);
49+
50+
51+
/**
52+
* Count the rows in the given table.
53+
*
54+
* @param jdbcTemplate the JdbcTemplate with which to perform JDBC operations
55+
* @param tableName name of the table to count rows in
56+
* @return the number of rows in the table
57+
* @since 3.2
58+
*/
59+
public static int countRowsInTable(JdbcTemplate jdbcTemplate, String tableName) {
60+
return jdbcTemplate.queryForInt("SELECT COUNT(0) FROM " + tableName);
61+
}
62+
63+
/**
64+
* Count the rows in the given table, using the provided {@code WHERE} clause.
65+
*
66+
* <p>If the provided {@code WHERE} clause contains text, it will be prefixed
67+
* with {@code " WHERE "} and then appended to the generated {@code SELECT}
68+
* statement. For example, if the provided table name is {@code "person"} and
69+
* the provided where clause is {@code "name = 'Bob' and age > 25"}, the
70+
* resulting SQL statement to execute will be
71+
* {@code "SELECT COUNT(0) FROM person WHERE name = 'Bob' and age > 25"}.
72+
*
73+
* @param jdbcTemplate the JdbcTemplate with which to perform JDBC operations
74+
* @param tableName the name of the table to count rows in
75+
* @param whereClause the {@code WHERE} clause to append to the query
76+
* @return the number of rows in the table that match the provided
77+
* {@code WHERE} clause
78+
* @since 3.2
79+
*/
80+
public static int countRowsInTableWhere(JdbcTemplate jdbcTemplate, String tableName, String whereClause) {
81+
String sql = "SELECT COUNT(0) FROM " + tableName;
82+
83+
if (StringUtils.hasText(whereClause)) {
84+
sql += " WHERE " + whereClause;
85+
}
86+
87+
return jdbcTemplate.queryForInt(sql);
88+
}
89+
90+
/**
91+
* Delete all rows from the specified tables.
92+
*
93+
* @param jdbcTemplate the JdbcTemplate with which to perform JDBC operations
94+
* @param tableNames the names of the tables to delete from
95+
* @return the total number of rows deleted from all specified tables
96+
* @since 3.2
97+
*/
98+
public static int deleteFromTables(JdbcTemplate jdbcTemplate, String... tableNames) {
99+
int totalRowCount = 0;
100+
for (String tableName : tableNames) {
101+
int rowCount = jdbcTemplate.update("DELETE FROM " + tableName);
102+
totalRowCount += rowCount;
103+
if (logger.isInfoEnabled()) {
104+
logger.info("Deleted " + rowCount + " rows from table " + tableName);
105+
}
106+
}
107+
return totalRowCount;
108+
}
109+
110+
/**
111+
* Drop the specified tables.
112+
*
113+
* @param jdbcTemplate the JdbcTemplate with which to perform JDBC operations
114+
* @param tableNames the names of the tables to drop
115+
* @since 3.2
116+
*/
117+
public static void dropTables(JdbcTemplate jdbcTemplate, String... tableNames) {
118+
for (String tableName : tableNames) {
119+
jdbcTemplate.execute("DROP TABLE " + tableName);
120+
if (logger.isInfoEnabled()) {
121+
logger.info("Dropped table " + tableName);
122+
}
123+
}
124+
}
125+
34126
/**
35-
* Read a script from the LineNumberReader and build a String containing the
36-
* lines.
37-
*
38-
* @param lineNumberReader the <code>LineNumberReader</code> containing the
39-
* script to be processed
40-
* @return <code>String</code> containing the script lines
41-
* @throws IOException
127+
* Execute the given SQL script.
128+
*
129+
* <p>The script will typically be loaded from the classpath. There should
130+
* be one statement per line. Any semicolons will be removed.
131+
*
132+
* <p><b>Do not use this method to execute DDL if you expect rollback.</b>
133+
*
134+
* @param jdbcTemplate the JdbcTemplate with which to perform JDBC operations
135+
* @param resourceLoader the resource loader with which to load the SQL script
136+
* @param sqlResourcePath the Spring resource path for the SQL script
137+
* @param continueOnError whether or not to continue without throwing an
138+
* exception in the event of an error
139+
* @throws DataAccessException if there is an error executing a statement
140+
* and {@code continueOnError} is {@code false}
141+
* @since 3.2
142+
*/
143+
public static void executeSqlScript(JdbcTemplate jdbcTemplate, ResourceLoader resourceLoader,
144+
String sqlResourcePath, boolean continueOnError) throws DataAccessException {
145+
Resource resource = resourceLoader.getResource(sqlResourcePath);
146+
executeSqlScript(jdbcTemplate, resource, continueOnError);
147+
}
148+
149+
/**
150+
* Execute the given SQL script.
151+
*
152+
* <p>The script will typically be loaded from the classpath. Statements
153+
* should be delimited with a semicolon. If statements are not delimited with
154+
* a semicolon then there should be one statement per line. Statements are
155+
* allowed to span lines only if they are delimited with a semicolon.
156+
*
157+
* <p><b>Do not use this method to execute DDL if you expect rollback.</b>
158+
*
159+
* @param jdbcTemplate the JdbcTemplate with which to perform JDBC operations
160+
* @param resource the resource to load the SQL script from
161+
* @param continueOnError whether or not to continue without throwing an
162+
* exception in the event of an error
163+
* @throws DataAccessException if there is an error executing a statement
164+
* and {@code continueOnError} is {@code false}
165+
* @since 3.2
166+
*/
167+
public static void executeSqlScript(JdbcTemplate jdbcTemplate, Resource resource, boolean continueOnError)
168+
throws DataAccessException {
169+
executeSqlScript(jdbcTemplate, new EncodedResource(resource), continueOnError);
170+
}
171+
172+
/**
173+
* Execute the given SQL script.
174+
*
175+
* <p>The script will typically be loaded from the classpath. There should
176+
* be one statement per line. Any semicolons will be removed.
177+
*
178+
* <p><b>Do not use this method to execute DDL if you expect rollback.</b>
179+
*
180+
* @param jdbcTemplate the JdbcTemplate with which to perform JDBC operations
181+
* @param resource the resource (potentially associated with a specific encoding)
182+
* to load the SQL script from
183+
* @param continueOnError whether or not to continue without throwing an
184+
* exception in the event of an error
185+
* @throws DataAccessException if there is an error executing a statement
186+
* and {@code continueOnError} is {@code false}
187+
* @since 3.2
188+
*/
189+
public static void executeSqlScript(JdbcTemplate jdbcTemplate, EncodedResource resource, boolean continueOnError)
190+
throws DataAccessException {
191+
192+
if (logger.isInfoEnabled()) {
193+
logger.info("Executing SQL script from " + resource);
194+
}
195+
196+
long startTime = System.currentTimeMillis();
197+
List<String> statements = new LinkedList<String>();
198+
LineNumberReader reader = null;
199+
try {
200+
reader = new LineNumberReader(resource.getReader());
201+
String script = readScript(reader);
202+
char delimiter = ';';
203+
if (!containsSqlScriptDelimiters(script, delimiter)) {
204+
delimiter = '\n';
205+
}
206+
splitSqlScript(script, delimiter, statements);
207+
for (String statement : statements) {
208+
try {
209+
int rowsAffected = jdbcTemplate.update(statement);
210+
if (logger.isDebugEnabled()) {
211+
logger.debug(rowsAffected + " rows affected by SQL: " + statement);
212+
}
213+
} catch (DataAccessException ex) {
214+
if (continueOnError) {
215+
if (logger.isWarnEnabled()) {
216+
logger.warn("SQL statement [" + statement + "] failed", ex);
217+
}
218+
} else {
219+
throw ex;
220+
}
221+
}
222+
}
223+
long elapsedTime = System.currentTimeMillis() - startTime;
224+
if (logger.isInfoEnabled()) {
225+
logger.info(String.format("Executed SQL script from %s in %s ms.", resource, elapsedTime));
226+
}
227+
} catch (IOException ex) {
228+
throw new DataAccessResourceFailureException("Failed to open SQL script from " + resource, ex);
229+
} finally {
230+
try {
231+
if (reader != null) {
232+
reader.close();
233+
}
234+
} catch (IOException ex) {
235+
// ignore
236+
}
237+
}
238+
}
239+
240+
/**
241+
* Read a script from the provided {@code LineNumberReader} and build a
242+
* {@code String} containing the lines.
243+
*
244+
* @param lineNumberReader the {@code LineNumberReader} containing the script
245+
* to be processed
246+
* @return a {@code String} containing the script lines
42247
*/
43248
public static String readScript(LineNumberReader lineNumberReader) throws IOException {
44249
String currentStatement = lineNumberReader.readLine();
@@ -56,11 +261,13 @@ public static String readScript(LineNumberReader lineNumberReader) throws IOExce
56261
}
57262

58263
/**
59-
* Does the provided SQL script contain the specified delimiter?
60-
*
264+
* Determine if the provided SQL script contains the specified delimiter.
265+
*
61266
* @param script the SQL script
62-
* @param delim character delimiting each statement - typically a ';'
267+
* @param delim character delimiting each statement &mdash; typically a ';'
63268
* character
269+
* @return {@code true} if the script contains the delimiter; {@code false}
270+
* otherwise
64271
*/
65272
public static boolean containsSqlScriptDelimiters(String script, char delim) {
66273
boolean inLiteral = false;
@@ -80,11 +287,11 @@ public static boolean containsSqlScriptDelimiters(String script, char delim) {
80287
* Split an SQL script into separate statements delimited with the provided
81288
* delimiter character. Each individual statement will be added to the
82289
* provided <code>List</code>.
83-
*
290+
*
84291
* @param script the SQL script
85-
* @param delim character delimiting each statement - typically a ';'
292+
* @param delim character delimiting each statement &mdash; typically a ';'
86293
* character
87-
* @param statements the List that will contain the individual statements
294+
* @param statements the list that will contain the individual statements
88295
*/
89296
public static void splitSqlScript(String script, char delim, List<String> statements) {
90297
StringBuilder sb = new StringBuilder();
@@ -99,8 +306,7 @@ public static void splitSqlScript(String script, char delim, List<String> statem
99306
statements.add(sb.toString());
100307
sb = new StringBuilder();
101308
}
102-
}
103-
else {
309+
} else {
104310
sb.append(content[i]);
105311
}
106312
}

spring-test/src/main/java/org/springframework/test/jdbc/SimpleJdbcTestUtils.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.io.IOException;
2020
import java.io.LineNumberReader;
21+
2122
import java.util.LinkedList;
2223
import java.util.List;
2324

@@ -39,8 +40,9 @@
3940
* @author Juergen Hoeller
4041
* @author Thomas Risberg
4142
* @since 2.5
43+
* @deprecated As of Spring 3.2, use {@link JdbcTestUtils} instead.
4244
*/
43-
@SuppressWarnings("deprecation")
45+
@Deprecated
4446
public abstract class SimpleJdbcTestUtils {
4547

4648
private static final Log logger = LogFactory.getLog(SimpleJdbcTestUtils.class);

src/dist/changelog.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ Changes in version 3.2 M2 (2012-08-xx)
3030
* introduced support for single, unqualified tx manager in the TestContext framework (SPR-9645)
3131
* introduced support for TransactionManagementConfigurer in the TestContext framework (SPR-9604)
3232
* introduced MockEnvironment in the spring-test module (SPR-9492)
33+
* deprecated SimpleJdbcTestUtils in favor of JdbcTestUtils (SPR-9235)
34+
* introduced countRowsInTableWhere() and dropTables() in JdbcTestUtils (SPR-9235)
3335

3436

3537
Changes in version 3.2 M1 (2012-05-28)

0 commit comments

Comments
 (0)