/* * Copyright 2002-2008 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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.easymock.MockControl; import org.apache.commons.logging.LogFactory; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.AbstractJdbcTests; import org.springframework.jdbc.Customer; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.PreparedStatementCallback; import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.SqlParameterValue; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.AssertThrows; /** * @author Rick Evans * @author Juergen Hoeller */ public class NamedParameterJdbcTemplateTests extends AbstractJdbcTests { private static final String SELECT_NAMED_PARAMETERS = "select id, forename from custmr where id = :id and country = :country"; private static final String SELECT_NAMED_PARAMETERS_PARSED = "select id, forename from custmr where id = ? and country = ?"; private static final String UPDATE_NAMED_PARAMETERS = "update seat_status set booking_id = null where performance_id = :perfId and price_band_id = :priceId"; private static final String UPDATE_NAMED_PARAMETERS_PARSED = "update seat_status set booking_id = null where performance_id = ? and price_band_id = ?"; private static final String[] COLUMN_NAMES = new String[] {"id", "forename"}; private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); private MockControl ctrlPreparedStatement; private PreparedStatement mockPreparedStatement; private MockControl ctrlResultSet; private ResultSet mockResultSet; protected void setUp() throws Exception { super.setUp(); ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); ctrlResultSet = MockControl.createControl(ResultSet.class); mockResultSet = (ResultSet) ctrlResultSet.getMock(); } protected void tearDown() throws Exception { super.tearDown(); if (shouldVerify()) { ctrlPreparedStatement.verify(); ctrlResultSet.verify(); } } protected void replay() { super.replay(); ctrlPreparedStatement.replay(); ctrlResultSet.replay(); } public void testNullDataSourceProvidedToCtor() throws Exception { new AssertThrows(IllegalArgumentException.class) { public void test() throws Exception { new NamedParameterJdbcTemplate((DataSource) null); } }.runTest(); } public void testNullJdbcTemplateProvidedToCtor() throws Exception { new AssertThrows(IllegalArgumentException.class) { public void test() throws Exception { new NamedParameterJdbcTemplate((JdbcOperations) null); } }.runTest(); } public void testExecute() throws SQLException { mockPreparedStatement.setObject(1, new Integer(1)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setObject(2, new Integer(1)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("perfId", new Integer(1)); params.put("priceId", new Integer(1)); assertEquals("result", jt.execute(UPDATE_NAMED_PARAMETERS, params, new PreparedStatementCallback() { public Object doInPreparedStatement(PreparedStatement ps) throws SQLException { assertEquals(mockPreparedStatement, ps); ps.executeUpdate(); return "result"; } })); } public void testExecuteWithTypedParameters() throws SQLException { mockPreparedStatement.setObject(1, new Integer(1), Types.DECIMAL); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setObject(2, new Integer(1), Types.INTEGER); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("perfId", new SqlParameterValue(Types.DECIMAL, new Integer(1))); params.put("priceId", new SqlParameterValue(Types.INTEGER, new Integer(1))); assertEquals("result", jt.execute(UPDATE_NAMED_PARAMETERS, params, new PreparedStatementCallback() { public Object doInPreparedStatement(PreparedStatement ps) throws SQLException { assertEquals(mockPreparedStatement, ps); ps.executeUpdate(); return "result"; } })); } public void testUpdate() throws SQLException { mockPreparedStatement.setObject(1, new Integer(1)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setObject(2, new Integer(1)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("perfId", new Integer(1)); params.put("priceId", new Integer(1)); int rowsAffected = jt.update(UPDATE_NAMED_PARAMETERS, params); assertEquals(1, rowsAffected); } public void testUpdateWithTypedParameters() throws SQLException { mockPreparedStatement.setObject(1, new Integer(1), Types.DECIMAL); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setObject(2, new Integer(1), Types.INTEGER); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("perfId", new SqlParameterValue(Types.DECIMAL, new Integer(1))); params.put("priceId", new SqlParameterValue(Types.INTEGER, new Integer(1))); int rowsAffected = jt.update(UPDATE_NAMED_PARAMETERS, params); assertEquals(1, rowsAffected); } public void testQueryWithResultSetExtractor() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(1), Types.DECIMAL); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setString(2, "UK"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("id", new SqlParameterValue(Types.DECIMAL, new Integer(1))); params.put("country", "UK"); Customer cust = (Customer) jt.query(SELECT_NAMED_PARAMETERS, params, new ResultSetExtractor() { public Object extractData(ResultSet rs) throws SQLException, DataAccessException { rs.next(); Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } }); assertTrue("Customer id was assigned correctly", cust.getId() == 1); assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod")); } public void testQueryWithRowCallbackHandler() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(1), Types.DECIMAL); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setString(2, "UK"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("id", new SqlParameterValue(Types.DECIMAL, new Integer(1))); params.put("country", "UK"); final List customers = new LinkedList(); jt.query(SELECT_NAMED_PARAMETERS, params, new RowCallbackHandler() { public void processRow(ResultSet rs) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); customers.add(cust); } }); assertEquals(1, customers.size()); Customer cust = (Customer) customers.get(0); assertTrue("Customer id was assigned correctly", cust.getId() == 1); assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod")); } public void testQueryWithRowMapper() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(1), Types.DECIMAL); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setString(2, "UK"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("id", new SqlParameterValue(Types.DECIMAL, new Integer(1))); params.put("country", "UK"); List customers = jt.query(SELECT_NAMED_PARAMETERS, params, new RowMapper() { public Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } }); assertEquals(1, customers.size()); Customer cust = (Customer) customers.get(0); assertTrue("Customer id was assigned correctly", cust.getId() == 1); assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod")); } public void testQueryForObjectWithRowMapper() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(1), Types.DECIMAL); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setString(2, "UK"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("id", new SqlParameterValue(Types.DECIMAL, new Integer(1))); params.put("country", "UK"); Customer cust = (Customer) jt.queryForObject(SELECT_NAMED_PARAMETERS, params, new RowMapper() { public Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } }); assertTrue("Customer id was assigned correctly", cust.getId() == 1); assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod")); } }