Introduce queryForStream on JdbcTemplate and NamedParameterJdbcTemplate

Closes gh-18474
This commit is contained in:
Juergen Hoeller
2020-05-19 14:08:52 +02:00
parent 5ca7928153
commit d56ca04162
6 changed files with 417 additions and 75 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@@ -26,6 +26,8 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;
import javax.sql.DataSource;
@@ -164,8 +166,24 @@ public class JdbcTemplateQueryTests {
return rs.getInt(1);
}
});
boolean condition = o instanceof Integer;
assertThat(condition).as("Correct result type").isTrue();
assertThat(o instanceof Integer).as("Correct result type").isTrue();
verify(this.resultSet).close();
verify(this.statement).close();
}
@Test
public void testQueryForStreamWithRowMapper() throws Exception {
String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3";
given(this.resultSet.next()).willReturn(true, false);
given(this.resultSet.getInt(1)).willReturn(22);
AtomicInteger count = new AtomicInteger();
try (Stream<Integer> s = this.template.queryForStream(sql, (rs, rowNum) -> rs.getInt(1))) {
s.forEach(val -> {
count.incrementAndGet();
assertThat(val).isEqualTo(22);
});
}
assertThat(count.get()).isEqualTo(1);
verify(this.resultSet).close();
verify(this.statement).close();
}
@@ -278,7 +296,7 @@ public class JdbcTemplateQueryTests {
private void doTestQueryForListWithArgs(String sql) throws Exception {
given(this.resultSet.next()).willReturn(true, true, false);
given(this.resultSet.getObject(1)).willReturn(11, 12);
List<Map<String, Object>> li = this.template.queryForList(sql, new Object[] {3});
List<Map<String, Object>> li = this.template.queryForList(sql, 3);
assertThat(li.size()).as("All rows returned").isEqualTo(2);
assertThat(((Integer) li.get(0).get("age")).intValue()).as("First row is Integer").isEqualTo(11);
assertThat(((Integer) li.get(1).get("age")).intValue()).as("Second row is Integer").isEqualTo(12);
@@ -291,7 +309,7 @@ public class JdbcTemplateQueryTests {
public void testQueryForListWithArgsAndEmptyResult() throws Exception {
String sql = "SELECT AGE FROM CUSTMR WHERE ID < ?";
given(this.resultSet.next()).willReturn(false);
List<Map<String, Object>> li = this.template.queryForList(sql, new Object[] {3});
List<Map<String, Object>> li = this.template.queryForList(sql, 3);
assertThat(li.size()).as("All rows returned").isEqualTo(0);
verify(this.preparedStatement).setObject(1, 3);
verify(this.resultSet).close();
@@ -303,7 +321,7 @@ public class JdbcTemplateQueryTests {
String sql = "SELECT AGE FROM CUSTMR WHERE ID < ?";
given(this.resultSet.next()).willReturn(true, false);
given(this.resultSet.getObject(1)).willReturn(11);
List<Map<String, Object>> li = this.template.queryForList(sql, new Object[] {3});
List<Map<String, Object>> li = this.template.queryForList(sql, 3);
assertThat(li.size()).as("All rows returned").isEqualTo(1);
assertThat(((Integer) li.get(0).get("age")).intValue()).as("First row is Integer").isEqualTo(11);
verify(this.preparedStatement).setObject(1, 3);
@@ -316,7 +334,7 @@ public class JdbcTemplateQueryTests {
String sql = "SELECT AGE FROM CUSTMR WHERE ID < ?";
given(this.resultSet.next()).willReturn(true, false);
given(this.resultSet.getInt(1)).willReturn(11);
List<Integer> li = this.template.queryForList(sql, new Object[] {3}, Integer.class);
List<Integer> li = this.template.queryForList(sql, Integer.class, 3);
assertThat(li.size()).as("All rows returned").isEqualTo(1);
assertThat(li.get(0).intValue()).as("First row is Integer").isEqualTo(11);
verify(this.preparedStatement).setObject(1, 3);
@@ -329,7 +347,7 @@ public class JdbcTemplateQueryTests {
String sql = "SELECT AGE FROM CUSTMR WHERE ID < ?";
given(this.resultSet.next()).willReturn(true, false);
given(this.resultSet.getObject(1)).willReturn(11);
Map<String, Object> map = this.template.queryForMap(sql, new Object[] {3});
Map<String, Object> map = this.template.queryForMap(sql, 3);
assertThat(((Integer) map.get("age")).intValue()).as("Row is Integer").isEqualTo(11);
verify(this.preparedStatement).setObject(1, 3);
verify(this.resultSet).close();
@@ -341,14 +359,26 @@ public class JdbcTemplateQueryTests {
String sql = "SELECT AGE FROM CUSTMR WHERE ID = ?";
given(this.resultSet.next()).willReturn(true, false);
given(this.resultSet.getInt(1)).willReturn(22);
Object o = this.template.queryForObject(sql, new Object[] {3}, new RowMapper<Integer>() {
@Override
public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getInt(1);
}
});
boolean condition = o instanceof Integer;
assertThat(condition).as("Correct result type").isTrue();
Object o = this.template.queryForObject(sql, (rs, rowNum) -> rs.getInt(1), 3);
assertThat(o instanceof Integer).as("Correct result type").isTrue();
verify(this.preparedStatement).setObject(1, 3);
verify(this.resultSet).close();
verify(this.preparedStatement).close();
}
@Test
public void testQueryForStreamWithArgsAndRowMapper() throws Exception {
String sql = "SELECT AGE FROM CUSTMR WHERE ID = ?";
given(this.resultSet.next()).willReturn(true, false);
given(this.resultSet.getInt(1)).willReturn(22);
AtomicInteger count = new AtomicInteger();
try (Stream<Integer> s = this.template.queryForStream(sql, (rs, rowNum) -> rs.getInt(1), 3)) {
s.forEach(val -> {
count.incrementAndGet();
assertThat(val).isEqualTo(22);
});
}
assertThat(count.get()).isEqualTo(1);
verify(this.preparedStatement).setObject(1, 3);
verify(this.resultSet).close();
verify(this.preparedStatement).close();
@@ -359,9 +389,8 @@ public class JdbcTemplateQueryTests {
String sql = "SELECT AGE FROM CUSTMR WHERE ID = ?";
given(this.resultSet.next()).willReturn(true, false);
given(this.resultSet.getInt(1)).willReturn(22);
Object o = this.template.queryForObject(sql, new Object[] {3}, Integer.class);
boolean condition = o instanceof Integer;
assertThat(condition).as("Correct result type").isTrue();
Object o = this.template.queryForObject(sql, Integer.class, 3);
assertThat(o instanceof Integer).as("Correct result type").isTrue();
verify(this.preparedStatement).setObject(1, 3);
verify(this.resultSet).close();
verify(this.preparedStatement).close();
@@ -372,7 +401,7 @@ public class JdbcTemplateQueryTests {
String sql = "SELECT AGE FROM CUSTMR WHERE ID = ?";
given(this.resultSet.next()).willReturn(true, false);
given(this.resultSet.getInt(1)).willReturn(22);
int i = this.template.queryForObject(sql, new Object[] {3}, Integer.class).intValue();
int i = this.template.queryForObject(sql, Integer.class, 3).intValue();
assertThat(i).as("Return of an int").isEqualTo(22);
verify(this.preparedStatement).setObject(1, 3);
verify(this.resultSet).close();
@@ -384,7 +413,7 @@ public class JdbcTemplateQueryTests {
String sql = "SELECT AGE FROM CUSTMR WHERE ID = ?";
given(this.resultSet.next()).willReturn(true, false);
given(this.resultSet.getLong(1)).willReturn(87L);
long l = this.template.queryForObject(sql, new Object[] {3}, Long.class).longValue();
long l = this.template.queryForObject(sql, Long.class, 3).longValue();
assertThat(l).as("Return of a long").isEqualTo(87);
verify(this.preparedStatement).setObject(1, 3);
verify(this.resultSet).close();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@@ -28,6 +28,8 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;
import javax.sql.DataSource;
@@ -237,6 +239,7 @@ public class NamedParameterJdbcTemplateTests {
verify(connection).prepareStatement(SELECT_NAMED_PARAMETERS_PARSED);
verify(preparedStatement).setObject(1, 1, Types.DECIMAL);
verify(preparedStatement).setString(2, "UK");
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@@ -259,6 +262,7 @@ public class NamedParameterJdbcTemplateTests {
assertThat(cust.getId() == 1).as("Customer id was assigned correctly").isTrue();
assertThat(cust.getForename().equals("rod")).as("Customer forename was assigned correctly").isTrue();
verify(connection).prepareStatement(SELECT_NO_PARAMETERS);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@@ -285,6 +289,7 @@ public class NamedParameterJdbcTemplateTests {
verify(connection).prepareStatement(SELECT_NAMED_PARAMETERS_PARSED);
verify(preparedStatement).setObject(1, 1, Types.DECIMAL);
verify(preparedStatement).setString(2, "UK");
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@@ -307,6 +312,7 @@ public class NamedParameterJdbcTemplateTests {
assertThat(customers.get(0).getId() == 1).as("Customer id was assigned correctly").isTrue();
assertThat(customers.get(0).getForename().equals("rod")).as("Customer forename was assigned correctly").isTrue();
verify(connection).prepareStatement(SELECT_NO_PARAMETERS);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@@ -326,12 +332,14 @@ public class NamedParameterJdbcTemplateTests {
cust.setForename(rs.getString(COLUMN_NAMES[1]));
return cust;
});
assertThat(customers.size()).isEqualTo(1);
assertThat(customers.get(0).getId() == 1).as("Customer id was assigned correctly").isTrue();
assertThat(customers.get(0).getForename().equals("rod")).as("Customer forename was assigned correctly").isTrue();
verify(connection).prepareStatement(SELECT_NAMED_PARAMETERS_PARSED);
verify(preparedStatement).setObject(1, 1, Types.DECIMAL);
verify(preparedStatement).setString(2, "UK");
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@@ -349,10 +357,12 @@ public class NamedParameterJdbcTemplateTests {
cust.setForename(rs.getString(COLUMN_NAMES[1]));
return cust;
});
assertThat(customers.size()).isEqualTo(1);
assertThat(customers.get(0).getId() == 1).as("Customer id was assigned correctly").isTrue();
assertThat(customers.get(0).getForename().equals("rod")).as("Customer forename was assigned correctly").isTrue();
verify(connection).prepareStatement(SELECT_NO_PARAMETERS);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@@ -365,6 +375,7 @@ public class NamedParameterJdbcTemplateTests {
params.put("id", new SqlParameterValue(Types.DECIMAL, 1));
params.put("country", "UK");
Customer cust = namedParameterTemplate.queryForObject(SELECT_NAMED_PARAMETERS, params,
(rs, rownum) -> {
Customer cust1 = new Customer();
@@ -372,11 +383,46 @@ public class NamedParameterJdbcTemplateTests {
cust1.setForename(rs.getString(COLUMN_NAMES[1]));
return cust1;
});
assertThat(cust.getId() == 1).as("Customer id was assigned correctly").isTrue();
assertThat(cust.getForename().equals("rod")).as("Customer forename was assigned correctly").isTrue();
verify(connection).prepareStatement(SELECT_NAMED_PARAMETERS_PARSED);
verify(preparedStatement).setObject(1, 1, Types.DECIMAL);
verify(preparedStatement).setString(2, "UK");
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
public void testQueryForStreamWithRowMapper() throws SQLException {
given(resultSet.next()).willReturn(true, false);
given(resultSet.getInt("id")).willReturn(1);
given(resultSet.getString("forename")).willReturn("rod");
params.put("id", new SqlParameterValue(Types.DECIMAL, 1));
params.put("country", "UK");
AtomicInteger count = new AtomicInteger();
try (Stream<Customer> s = namedParameterTemplate.queryForStream(SELECT_NAMED_PARAMETERS, params,
(rs, rownum) -> {
Customer cust1 = new Customer();
cust1.setId(rs.getInt(COLUMN_NAMES[0]));
cust1.setForename(rs.getString(COLUMN_NAMES[1]));
return cust1;
})) {
s.forEach(cust -> {
count.incrementAndGet();
assertThat(cust.getId() == 1).as("Customer id was assigned correctly").isTrue();
assertThat(cust.getForename().equals("rod")).as("Customer forename was assigned correctly").isTrue();
});
}
assertThat(count.get()).isEqualTo(1);
verify(connection).prepareStatement(SELECT_NAMED_PARAMETERS_PARSED);
verify(preparedStatement).setObject(1, 1, Types.DECIMAL);
verify(preparedStatement).setString(2, "UK");
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}