Package org.springframework.jdbc.object

Source Code of org.springframework.jdbc.object.CustomerQuery

/*
* Copyright 2002-2014 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.object;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.jdbc.Customer;
import org.springframework.jdbc.core.SqlParameter;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;

/**
* @author Trevor Cook
* @author Thomas Risberg
* @author Juergen Hoeller
*/
public class SqlQueryTests  {

  //FIXME inline?
  private static final String SELECT_ID =
      "select id from custmr";
  private static final String SELECT_ID_WHERE =
      "select id from custmr where forename = ? and id = ?";
  private static final String SELECT_FORENAME =
      "select forename from custmr";
  private static final String SELECT_FORENAME_EMPTY =
      "select forename from custmr WHERE 1 = 2";
  private static final String SELECT_ID_FORENAME_WHERE =
      "select id, forename from prefix:custmr where forename = ?";
  private static final String SELECT_ID_FORENAME_NAMED_PARAMETERS =
      "select id, forename from custmr where id = :id and country = :country";
  private static final String SELECT_ID_FORENAME_NAMED_PARAMETERS_PARSED =
      "select id, forename from custmr where id = ? and country = ?";
  private static final String SELECT_ID_FORENAME_WHERE_ID_IN_LIST_1 =
      "select id, forename from custmr where id in (?, ?)";
  private static final String SELECT_ID_FORENAME_WHERE_ID_IN_LIST_2 =
      "select id, forename from custmr where id in (:ids)";
  private static final String SELECT_ID_FORENAME_WHERE_ID_REUSED_1 =
      "select id, forename from custmr where id = ? or id = ?)";
  private static final String SELECT_ID_FORENAME_WHERE_ID_REUSED_2 =
      "select id, forename from custmr where id = :id1 or id = :id1)";
  private static final String SELECT_ID_FORENAME_WHERE_ID =
      "select id, forename from custmr where id <= ?";

  private static final String[] COLUMN_NAMES = new String[] {"id", "forename"};
  private static final int[] COLUMN_TYPES = new int[] {Types.INTEGER, Types.VARCHAR};

  @Rule
  public ExpectedException thrown = ExpectedException.none();

  private Connection connection;
  private DataSource dataSource;
  private PreparedStatement preparedStatement;
  private ResultSet resultSet;


  @Before
  public void setUp() throws Exception {
    this.connection = mock(Connection.class);
    this.dataSource = mock(DataSource.class);
    this.preparedStatement = mock(PreparedStatement.class);
    this.resultSet = mock(ResultSet.class);
    given(this.dataSource.getConnection()).willReturn(this.connection);
    given(this.connection.prepareStatement(anyString())).willReturn(this.preparedStatement);
    given(preparedStatement.executeQuery()).willReturn(resultSet);
  }

  @Test
  public void testQueryWithoutParams() throws SQLException {
    given(resultSet.next()).willReturn(true, false);
    given(resultSet.getInt(1)).willReturn(1);

    SqlQuery<Integer> query = new MappingSqlQueryWithParameters<Integer>() {
      @Override
      protected Integer mapRow(ResultSet rs, int rownum, Object[] params, Map<? ,?> context)
          throws SQLException {
        assertTrue("params were null", params == null);
        assertTrue("context was null", context == null);
        return rs.getInt(1);
      }
    };
    query.setDataSource(dataSource);
    query.setSql(SELECT_ID);
    query.compile();
    List<Integer> list = query.execute();

    assertThat(list, is(equalTo(Arrays.asList(1))));
    verify(connection).prepareStatement(SELECT_ID);
    verify(resultSet).close();
    verify(preparedStatement).close();
  }

  @Test
  public void testQueryWithoutEnoughParams() {
    MappingSqlQuery<Integer> query = new MappingSqlQuery<Integer>() {
      @Override
      protected Integer mapRow(ResultSet rs, int rownum) throws SQLException {
        return rs.getInt(1);
      }
    };
    query.setDataSource(dataSource);
    query.setSql(SELECT_ID_WHERE);
    query.declareParameter(new SqlParameter(COLUMN_NAMES[0], COLUMN_TYPES[0]));
    query.declareParameter(new SqlParameter(COLUMN_NAMES[1], COLUMN_TYPES[1]));
    query.compile();

    thrown.expect(InvalidDataAccessApiUsageException.class);
    query.execute();
  }

  @Test
  public void testQueryWithMissingMapParams() {
    MappingSqlQuery<Integer> query = new MappingSqlQuery<Integer>() {
      @Override
      protected Integer mapRow(ResultSet rs, int rownum) throws SQLException {
        return rs.getInt(1);
      }
    };
    query.setDataSource(dataSource);
    query.setSql(SELECT_ID_WHERE);
    query.declareParameter(new SqlParameter(COLUMN_NAMES[0], COLUMN_TYPES[0]));
    query.declareParameter(new SqlParameter(COLUMN_NAMES[1], COLUMN_TYPES[1]));
    query.compile();

    thrown.expect(InvalidDataAccessApiUsageException.class);
    query.executeByNamedParam(Collections.singletonMap(COLUMN_NAMES[0], "value"));
  }

  @Test
  public void testStringQueryWithResults() throws Exception {
    String[] dbResults = new String[] { "alpha", "beta", "charlie" };
    given(resultSet.next()).willReturn(true, true, true, false);
    given(resultSet.getString(1)).willReturn(dbResults[0], dbResults[1], dbResults[2]);
    StringQuery query = new StringQuery(dataSource, SELECT_FORENAME);
    query.setRowsExpected(3);
    String[] results = query.run();
    assertThat(results, is(equalTo(dbResults)));
    verify(connection).prepareStatement(SELECT_FORENAME);
    verify(resultSet).close();
    verify(preparedStatement).close();
    verify(connection).close();
  }

  @Test
  public void testStringQueryWithoutResults() throws SQLException {
    given(resultSet.next()).willReturn(false);
    StringQuery query = new StringQuery(dataSource, SELECT_FORENAME_EMPTY);
    String[] results = query.run();
    assertThat(results, is(equalTo(new String[0])));
    verify(connection).prepareStatement(SELECT_FORENAME_EMPTY);
    verify(resultSet).close();
    verify(preparedStatement).close();
    verify(connection).close();
  }

  @Test
  public void testFindCustomerIntInt() throws SQLException {
    given(resultSet.next()).willReturn(true, false);
    given(resultSet.getInt("id")).willReturn(1);
    given(resultSet.getString("forename")).willReturn("rod");

    class CustomerQuery extends MappingSqlQuery<Customer> {

      public CustomerQuery(DataSource ds) {
        super(ds, SELECT_ID_WHERE);
        declareParameter(new SqlParameter(Types.NUMERIC));
        declareParameter(new SqlParameter(Types.NUMERIC));
        compile();
      }

      @Override
      protected Customer 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;
      }

      public Customer findCustomer(int id, int otherNum) {
        return findObject(id, otherNum);
      }
    }

    CustomerQuery query = new CustomerQuery(dataSource);
    Customer cust = query.findCustomer(1, 1);

    assertTrue("Customer id was assigned correctly", cust.getId() == 1);
    assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod"));
    verify(preparedStatement).setObject(1, 1, Types.NUMERIC);
    verify(preparedStatement).setObject(2, 1, Types.NUMERIC);
    verify(connection).prepareStatement(SELECT_ID_WHERE);
    verify(resultSet).close();
    verify(preparedStatement).close();
    verify(connection).close();
  }

  @Test
  public void testFindCustomerString() throws SQLException {
    given(resultSet.next()).willReturn(true, false);
    given(resultSet.getInt("id")).willReturn(1);
    given(resultSet.getString("forename")).willReturn("rod");

    class CustomerQuery extends MappingSqlQuery<Customer> {

      public CustomerQuery(DataSource ds) {
        super(ds, SELECT_ID_FORENAME_WHERE);
        declareParameter(new SqlParameter(Types.VARCHAR));
        compile();
      }

      @Override
      protected Customer 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;
      }

      public Customer findCustomer(String id) {
        return findObject(id);
      }
    }

    CustomerQuery query = new CustomerQuery(dataSource);
    Customer cust = query.findCustomer("rod");

    assertTrue("Customer id was assigned correctly", cust.getId() == 1);
    assertTrue("Customer forename was assigned correctly",
        cust.getForename().equals("rod"));
    verify(preparedStatement).setString(1, "rod");
    verify(connection).prepareStatement(SELECT_ID_FORENAME_WHERE);
    verify(resultSet).close();
    verify(preparedStatement).close();
    verify(connection).close();
  }

  @Test
  public void testFindCustomerMixed() throws SQLException {
    reset(connection);
    PreparedStatement preparedStatement2 = mock(PreparedStatement.class);
    ResultSet resultSet2 = mock(ResultSet.class);
    given(preparedStatement2.executeQuery()).willReturn(resultSet2);
    given(resultSet.next()).willReturn(true, false);
    given(resultSet.getInt("id")).willReturn(1);
    given(resultSet.getString("forename")).willReturn("rod");
    given(resultSet2.next()).willReturn(false);
    given(connection.prepareStatement(SELECT_ID_WHERE)).willReturn(preparedStatement, preparedStatement2);

    class CustomerQuery extends MappingSqlQuery<Customer> {

      public CustomerQuery(DataSource ds) {
        super(ds, SELECT_ID_WHERE);
        declareParameter(new SqlParameter(COLUMN_NAMES[0], COLUMN_TYPES[0]));
        declareParameter(new SqlParameter(COLUMN_NAMES[1], COLUMN_TYPES[1]));
        compile();
      }

      @Override
      protected Customer 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;
      }

      public Customer findCustomer(int id, String name) {
        return findObject(new Object[] { id, name });
      }
    }

    CustomerQuery query = new CustomerQuery(dataSource);

    Customer cust1 = query.findCustomer(1, "rod");
    assertTrue("Found customer", cust1 != null);
    assertTrue("Customer id was assigned correctly", cust1.getId() == 1);

    Customer cust2 = query.findCustomer(1, "Roger");
    assertTrue("No customer found", cust2 == null);

    verify(preparedStatement).setObject(1, 1, Types.INTEGER);
    verify(preparedStatement).setString(2, "rod");
    verify(preparedStatement2).setObject(1, 1, Types.INTEGER);
    verify(preparedStatement2).setString(2, "Roger");
    verify(resultSet).close();
    verify(resultSet2).close();
    verify(preparedStatement).close();
    verify(preparedStatement2).close();
    verify(connection, times(2)).close();
  }

  @Test
  public void testFindTooManyCustomers() throws SQLException {
    given(resultSet.next()).willReturn(true, true, false);
    given(resultSet.getInt("id")).willReturn(1, 2);
    given(resultSet.getString("forename")).willReturn("rod", "rod");

    class CustomerQuery extends MappingSqlQuery<Customer> {

      public CustomerQuery(DataSource ds) {
        super(ds, SELECT_ID_FORENAME_WHERE);
        declareParameter(new SqlParameter(Types.VARCHAR));
        compile();
      }

      @Override
      protected Customer 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;
      }

      public Customer findCustomer(String id) {
        return findObject(id);
      }
    }

    CustomerQuery query = new CustomerQuery(dataSource);
    thrown.expect(IncorrectResultSizeDataAccessException.class);
    try {
      query.findCustomer("rod");
    }
    finally {
      verify(preparedStatement).setString(1, "rod");
      verify(connection).prepareStatement(SELECT_ID_FORENAME_WHERE);
      verify(resultSet).close();
      verify(preparedStatement).close();
      verify(connection).close();
    }
  }

  @Test
  public void testListCustomersIntInt() throws SQLException {
    given(resultSet.next()).willReturn(true, true, false);
    given(resultSet.getInt("id")).willReturn(1, 2);
    given(resultSet.getString("forename")).willReturn("rod", "dave");

    class CustomerQuery extends MappingSqlQuery<Customer> {

      public CustomerQuery(DataSource ds) {
        super(ds, SELECT_ID_WHERE);
        declareParameter(new SqlParameter(Types.NUMERIC));
        declareParameter(new SqlParameter(Types.NUMERIC));
        compile();
      }

      @Override
      protected Customer 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;
      }
    }

    CustomerQuery query = new CustomerQuery(dataSource);
    List<Customer> list = query.execute(1, 1);
    assertTrue("2 results in list", list.size() == 2);
    assertThat(list.get(0).getForename(), is("rod"));
    assertThat(list.get(1).getForename(), is("dave"));
    verify(preparedStatement).setObject(1, 1, Types.NUMERIC);
    verify(preparedStatement).setObject(2, 1, Types.NUMERIC);
    verify(connection).prepareStatement(SELECT_ID_WHERE);
    verify(resultSet).close();
    verify(preparedStatement).close();
    verify(connection).close();
  }

  @Test
  public void testListCustomersString() throws SQLException {
    given(resultSet.next()).willReturn(true, true, false);
    given(resultSet.getInt("id")).willReturn(1, 2);
    given(resultSet.getString("forename")).willReturn("rod", "dave");

    class CustomerQuery extends MappingSqlQuery<Customer> {

      public CustomerQuery(DataSource ds) {
        super(ds, SELECT_ID_FORENAME_WHERE);
        declareParameter(new SqlParameter(Types.VARCHAR));
        compile();
      }

      @Override
      protected Customer 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;
      }
    }

    CustomerQuery query = new CustomerQuery(dataSource);
    List<Customer> list = query.execute("one");
    assertTrue("2 results in list", list.size() == 2);
    assertThat(list.get(0).getForename(), is("rod"));
    assertThat(list.get(1).getForename(), is("dave"));
    verify(preparedStatement).setString(1, "one");
    verify(connection).prepareStatement(SELECT_ID_FORENAME_WHERE);
    verify(resultSet).close();
    verify(preparedStatement).close();
    verify(connection).close();
  }

  @Test
  public void testFancyCustomerQuery() throws SQLException {
    given(resultSet.next()).willReturn(true, false);
    given(resultSet.getInt("id")).willReturn(1);
    given(resultSet.getString("forename")).willReturn("rod");

    given(connection.prepareStatement(SELECT_ID_FORENAME_WHERE,
        ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY)
      ).willReturn(preparedStatement);

    class CustomerQuery extends MappingSqlQuery<Customer> {

      public CustomerQuery(DataSource ds) {
        super(ds, SELECT_ID_FORENAME_WHERE);
        setResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE);
        declareParameter(new SqlParameter(Types.NUMERIC));
        compile();
      }

      @Override
      protected Customer 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;
      }

      public Customer findCustomer(int id) {
        return findObject(id);
      }
    }

    CustomerQuery query = new CustomerQuery(dataSource);
    Customer cust = query.findCustomer(1);
    assertTrue("Customer id was assigned correctly", cust.getId() == 1);
    assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod"));
    verify(preparedStatement).setObject(1, 1, Types.NUMERIC);
    verify(resultSet).close();
    verify(preparedStatement).close();
    verify(connection).close();
  }

  @Test
  public void testUnnamedParameterDeclarationWithNamedParameterQuery()
      throws SQLException {
    class CustomerQuery extends MappingSqlQuery<Customer> {

      public CustomerQuery(DataSource ds) {
        super(ds, SELECT_ID_FORENAME_WHERE);
        setResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE);
        declareParameter(new SqlParameter(Types.NUMERIC));
        compile();
      }

      @Override
      protected Customer 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;
      }

      public Customer findCustomer(int id) {
        Map<String, Integer> params = new HashMap<String, Integer>();
        params.put("id", id);
        return executeByNamedParam(params).get(0);
      }
    }

    // Query should not succeed since parameter declaration did not specify parameter name
    CustomerQuery query = new CustomerQuery(dataSource);
    thrown.expect(InvalidDataAccessApiUsageException.class);
    query.findCustomer(1);
  }

  @Test
  public void testNamedParameterCustomerQueryWithUnnamedDeclarations()
      throws SQLException {
    doTestNamedParameterCustomerQuery(false);
  }

  @Test
  public void testNamedParameterCustomerQueryWithNamedDeclarations()
      throws SQLException {
    doTestNamedParameterCustomerQuery(true);
  }

  private void doTestNamedParameterCustomerQuery(final boolean namedDeclarations)
      throws SQLException {
    given(resultSet.next()).willReturn(true, false);
    given(resultSet.getInt("id")).willReturn(1);
    given(resultSet.getString("forename")).willReturn("rod");
    given(connection.prepareStatement(SELECT_ID_FORENAME_NAMED_PARAMETERS_PARSED,
        ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY)
      ).willReturn(preparedStatement);

    class CustomerQuery extends MappingSqlQuery<Customer> {

      public CustomerQuery(DataSource ds) {
        super(ds, SELECT_ID_FORENAME_NAMED_PARAMETERS);
        setResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE);
        if (namedDeclarations) {
          declareParameter(new SqlParameter("country", Types.VARCHAR));
          declareParameter(new SqlParameter("id", Types.NUMERIC));
        }
        else {
          declareParameter(new SqlParameter(Types.NUMERIC));
          declareParameter(new SqlParameter(Types.VARCHAR));
        }
        compile();
      }

      @Override
      protected Customer 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;
      }

      public Customer findCustomer(int id, String country) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("id", id);
        params.put("country", country);
        return executeByNamedParam(params).get(0);
      }
    }

    CustomerQuery query = new CustomerQuery(dataSource);
    Customer cust = query.findCustomer(1, "UK");
    assertTrue("Customer id was assigned correctly", cust.getId() == 1);
    assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod"));
    verify(preparedStatement).setObject(1, 1, Types.NUMERIC);
    verify(preparedStatement).setString(2, "UK");
    verify(resultSet).close();
    verify(preparedStatement).close();
    verify(connection).close();
  }

  @Test
  public void testNamedParameterInListQuery() throws SQLException {
    given(resultSet.next()).willReturn(true, true, false);
    given(resultSet.getInt("id")).willReturn(1, 2);
    given(resultSet.getString("forename")).willReturn("rod", "juergen");

    given(connection.prepareStatement(SELECT_ID_FORENAME_WHERE_ID_IN_LIST_1,
        ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY)
      ).willReturn(preparedStatement);

    class CustomerQuery extends MappingSqlQuery<Customer> {

      public CustomerQuery(DataSource ds) {
        super(ds, SELECT_ID_FORENAME_WHERE_ID_IN_LIST_2);
        setResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE);
        declareParameter(new SqlParameter("ids", Types.NUMERIC));
        compile();
      }

      @Override
      protected Customer 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;
      }

      public List<Customer> findCustomers(List<Integer> ids) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("ids", ids);
        return executeByNamedParam(params);
      }
    }

    CustomerQuery query = new CustomerQuery(dataSource);
    List<Integer> ids = new ArrayList<Integer>();
    ids.add(1);
    ids.add(2);
    List<Customer> cust = query.findCustomers(ids);

    assertEquals("We got two customers back", cust.size(), 2);
    assertEquals("First customer id was assigned correctly", cust.get(0).getId(), 1);
    assertEquals("First customer forename was assigned correctly", cust.get(0).getForename(), "rod");
    assertEquals("Second customer id was assigned correctly", cust.get(1).getId(), 2);
    assertEquals("Second customer forename was assigned correctly", cust.get(1).getForename(), "juergen");
    verify(preparedStatement).setObject(1, 1, Types.NUMERIC);
    verify(preparedStatement).setObject(2, 2, Types.NUMERIC);
    verify(resultSet).close();
    verify(preparedStatement).close();
    verify(connection).close();
  }

  @Test
  public void testNamedParameterQueryReusingParameter() throws SQLException {
    given(resultSet.next()).willReturn(true, true, false);
    given(resultSet.getInt("id")).willReturn(1, 2);
    given(resultSet.getString("forename")).willReturn("rod", "juergen");

    given(connection.prepareStatement(SELECT_ID_FORENAME_WHERE_ID_REUSED_1,
        ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY)).willReturn(preparedStatement)
;

    class CustomerQuery extends MappingSqlQuery<Customer> {

      public CustomerQuery(DataSource ds) {
        super(ds, SELECT_ID_FORENAME_WHERE_ID_REUSED_2);
        setResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE);
        declareParameter(new SqlParameter("id1", Types.NUMERIC));
        compile();
      }

      @Override
      protected Customer 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;
      }

      public List<Customer> findCustomers(Integer id) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("id1", id);
        return executeByNamedParam(params);
      }
    }

    CustomerQuery query = new CustomerQuery(dataSource);
    List<Customer> cust = query.findCustomers(1);

    assertEquals("We got two customers back", cust.size(), 2);
    assertEquals("First customer id was assigned correctly", cust.get(0).getId(), 1);
    assertEquals("First customer forename was assigned correctly", cust.get(0).getForename(), "rod");
    assertEquals("Second customer id was assigned correctly", cust.get(1).getId(), 2);
    assertEquals("Second customer forename was assigned correctly", cust.get(1).getForename(), "juergen");

    verify(preparedStatement).setObject(1, 1, Types.NUMERIC);
    verify(preparedStatement).setObject(2, 1, Types.NUMERIC);
    verify(resultSet).close();
    verify(preparedStatement).close();
    verify(connection).close();
  }

  @Test
  public void testNamedParameterUsingInvalidQuestionMarkPlaceHolders()
      throws SQLException {
    given(
    connection.prepareStatement(SELECT_ID_FORENAME_WHERE_ID_REUSED_1,
        ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY)).willReturn(preparedStatement);

    class CustomerQuery extends MappingSqlQuery<Customer> {

      public CustomerQuery(DataSource ds) {
        super(ds, SELECT_ID_FORENAME_WHERE_ID_REUSED_1);
        setResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE);
        declareParameter(new SqlParameter("id1", Types.NUMERIC));
        compile();
      }

      @Override
      protected Customer 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;
      }

      public List<Customer> findCustomers(Integer id1) {
        Map<String, Integer> params = new HashMap<String, Integer>();
        params.put("id1", id1);
        return executeByNamedParam(params);
      }
    }

    CustomerQuery query = new CustomerQuery(dataSource);
    thrown.expect(InvalidDataAccessApiUsageException.class);
    query.findCustomers(1);
  }

  @Test
  public void testUpdateCustomers() throws SQLException {
    given(resultSet.next()).willReturn(true, true, false);
    given(resultSet.getInt("id")).willReturn(1, 2);
    given(connection.prepareStatement(SELECT_ID_FORENAME_WHERE_ID,
        ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)
      ).willReturn(preparedStatement);

    class CustomerUpdateQuery extends UpdatableSqlQuery<Customer> {

      public CustomerUpdateQuery(DataSource ds) {
        super(ds, SELECT_ID_FORENAME_WHERE_ID);
        declareParameter(new SqlParameter(Types.NUMERIC));
        compile();
      }

      @Override
      protected Customer updateRow(ResultSet rs, int rownum, Map<? ,?> context)
          throws SQLException {
        rs.updateString(2, "" + context.get(rs.getInt(COLUMN_NAMES[0])));
        return null;
      }
    }

    CustomerUpdateQuery query = new CustomerUpdateQuery(dataSource);
    Map<Integer, String> values = new HashMap<Integer, String>(2);
    values.put(1, "Rod");
    values.put(2, "Thomas");
    query.execute(2, values);
    verify(resultSet).updateString(2, "Rod");
    verify(resultSet).updateString(2, "Thomas");
    verify(resultSet, times(2)).updateRow();
    verify(preparedStatement).setObject(1, 2, Types.NUMERIC);
    verify(resultSet).close();
    verify(preparedStatement).close();
    verify(connection).close();
  }

  private static class StringQuery extends MappingSqlQuery<String> {

    public StringQuery(DataSource ds, String sql) {
      super(ds, sql);
      compile();
    }

    @Override
    protected String mapRow(ResultSet rs, int rownum) throws SQLException {
      return rs.getString(1);
    }

    public String[] run() {
      List<String> list = execute();
      String[] results = list.toArray(new String[list.size()]);
      return results;
    }
  }

}
TOP

Related Classes of org.springframework.jdbc.object.CustomerQuery

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.