diff --git a/spring-test/src/main/java/org/springframework/test/jdbc/JdbcTestUtils.java b/spring-test/src/main/java/org/springframework/test/jdbc/JdbcTestUtils.java index 532a82c01f..e096df5caa 100644 --- a/spring-test/src/main/java/org/springframework/test/jdbc/JdbcTestUtils.java +++ b/spring-test/src/main/java/org/springframework/test/jdbc/JdbcTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,13 +23,13 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.support.EncodedResource; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.SqlParameterValue; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; import org.springframework.util.StringUtils; @@ -103,6 +103,39 @@ public class JdbcTestUtils { return totalRowCount; } + /** + * Delete rows from the given table, using the provided {@code WHERE} clause. + *
If the provided {@code WHERE} clause contains text, it will be prefixed + * with {@code " WHERE "} and then appended to the generated {@code DELETE} + * statement. For example, if the provided table name is {@code "person"} and + * the provided where clause is {@code "name = 'Bob' and age > 25"}, the + * resulting SQL statement to execute will be + * {@code "DELETE FROM person WHERE name = 'Bob' and age > 25"}. + *
As an alternative to hard-coded values, the {@code "?"} placeholder can + * be used within the {@code WHERE} clause, binding to the given arguments. + * @param jdbcTemplate the JdbcTemplate with which to perform JDBC operations + * @param tableName the name of the table to delete rows in + * @param whereClause the {@code WHERE} clause to append to the query + * @param args arguments to bind to the query (leaving it to the PreparedStatement + * to guess the corresponding SQL type); may also contain {@link SqlParameterValue} + * objects which indicate not only the argument value but also the SQL type and + * optionally the scale. + * @return the number of rows deleted from the table + */ + public static int deleteFromTableWhere(JdbcTemplate jdbcTemplate, String tableName, + String whereClause, Object... args) { + String sql = "DELETE FROM " + tableName; + if(StringUtils.hasText(whereClause)) { + sql += " WHERE " + whereClause; + } + int rowCount = (args != null && args.length > 0 ? jdbcTemplate.update(sql, args) + : jdbcTemplate.update(sql)); + if (logger.isInfoEnabled()) { + logger.info("Deleted " + rowCount + " rows from table " + tableName); + } + return rowCount; + } + /** * Drop the specified tables. * @param jdbcTemplate the JdbcTemplate with which to perform JDBC operations diff --git a/spring-test/src/test/java/org/springframework/test/jdbc/JdbcTestUtilsTests.java b/spring-test/src/test/java/org/springframework/test/jdbc/JdbcTestUtilsTests.java index d5fd1b68e4..6ebdf91819 100644 --- a/spring-test/src/test/java/org/springframework/test/jdbc/JdbcTestUtilsTests.java +++ b/spring-test/src/test/java/org/springframework/test/jdbc/JdbcTestUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,25 +16,38 @@ package org.springframework.test.jdbc; -import static org.junit.Assert.*; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.BDDMockito.given; import java.io.LineNumberReader; import java.util.ArrayList; import java.util.List; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.support.EncodedResource; +import org.springframework.jdbc.core.JdbcTemplate; /** * Unit tests for {@link JdbcTestUtils}. * * @author Thomas Risberg * @author Sam Brannen + * @author Phillip Webb * @since 2.5.4 */ +@RunWith(MockitoJUnitRunner.class) public class JdbcTestUtilsTests { + @Mock + private JdbcTemplate jdbcTemplate; + @Test public void containsDelimiters() { assertTrue("test with ';' is wrong", !JdbcTestUtils.containsSqlScriptDelimiters("select 1\n select ';'", ';')); @@ -104,4 +117,26 @@ public class JdbcTestUtilsTests { assertEquals("statement 4 not split correctly", statement4, statements.get(3)); } + @Test + public void testDeleteNoWhere() throws Exception { + given(jdbcTemplate.update("DELETE FROM person")).willReturn(10); + int deleted = JdbcTestUtils.deleteFromTableWhere(jdbcTemplate, "person", null); + assertThat(deleted, equalTo(10)); + } + + @Test + public void testDeleteWhere() throws Exception { + given(jdbcTemplate.update("DELETE FROM person WHERE name = 'Bob' and age > 25")).willReturn(10); + int deleted = JdbcTestUtils.deleteFromTableWhere(jdbcTemplate, "person", "name = 'Bob' and age > 25"); + assertThat(deleted, equalTo(10)); + } + + @Test + public void deleteWhereAndArguments() throws Exception { + given(jdbcTemplate.update("DELETE FROM person WHERE name = ? and age > ?", "Bob", 25)).willReturn(10); + int deleted = JdbcTestUtils.deleteFromTableWhere(jdbcTemplate, "person", "name = ? and age > ?", "Bob", 25); + assertThat(deleted, equalTo(10)); + } + + }