Skip to content

Commit d7fd70f

Browse files
committed
deprecated SimpleJdbcTestUtils in favor of JdbcTestUtils; introduced "countRowsInTableWhere()" and "dropTables()" in JdbcTestUtils
Issue: SPR-9235 Issue: SPR-9664
1 parent fbe955a commit d7fd70f

File tree

2 files changed

+205
-21
lines changed

2 files changed

+205
-21
lines changed

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

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

58244
/**
59-
* Does the provided SQL script contain the specified delimiter?
60-
*
245+
* Determine if the provided SQL script contains the specified delimiter.
61246
* @param script the SQL script
62-
* @param delim character delimiting each statement - typically a ';'
63-
* character
247+
* @param delim character delimiting each statement &mdash; typically a ';' character
248+
* @return {@code true} if the script contains the delimiter; {@code false} otherwise
64249
*/
65250
public static boolean containsSqlScriptDelimiters(String script, char delim) {
66251
boolean inLiteral = false;
@@ -80,11 +265,9 @@ public static boolean containsSqlScriptDelimiters(String script, char delim) {
80265
* Split an SQL script into separate statements delimited with the provided
81266
* delimiter character. Each individual statement will be added to the
82267
* provided <code>List</code>.
83-
*
84268
* @param script the SQL script
85-
* @param delim character delimiting each statement - typically a ';'
86-
* character
87-
* @param statements the List that will contain the individual statements
269+
* @param delim character delimiting each statement &mdash; typically a ';' character
270+
* @param statements the list that will contain the individual statements
88271
*/
89272
public static void splitSqlScript(String script, char delim, List<String> statements) {
90273
StringBuilder sb = new StringBuilder();

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2011 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.
@@ -39,8 +39,9 @@
3939
* @author Juergen Hoeller
4040
* @author Thomas Risberg
4141
* @since 2.5
42+
* @deprecated as of Spring 3.1.3; use {@link JdbcTestUtils} instead.
4243
*/
43-
@SuppressWarnings("deprecation")
44+
@Deprecated
4445
public abstract class SimpleJdbcTestUtils {
4546

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

0 commit comments

Comments
 (0)