Can someone tell me what is the issue in following example code. For sake of example, We can assume all columns are available in resultSet and everything is a String.
Last line in below code is failing.
ResultSet rs = JdbcTemplate.query(......)
List<String> columnName= <some predefined fixed values> ;
Map<String,String> columnAndValueMap
= columnName
.stream()
.collect(Collectors.toMap(
Function.identity(),
rs::getString)); //Cannot resolve method 'getString'
Collectors.toMap
expects a Function<String, String>
as its second argument (the value mapper function).
Function<String, String>
is a functional interface that has this single abstract method:
String apply(String arg);
However, the ResultSet.getString
method has the following signature:
String getString(String columnLabel) throws SQLException;
As SQLException
is a checked exception, it makes the ResultSet.getString
method incompatible with the Function.apply
method, hence you're getting that error.
As shown by @vphilipnyc in their answer , you can use a for
loop with a try/catch
block to handle your scenario. Or, if you want to stick to a more functional approach, you might declare your own functional interface, that adapts a SQLException
throwing function to a common java.util.function.Function
(via inheritance):
@FunctionalInterface
public interface SQLFunction<T, R> extends Function<T, R> {
R applySQL(T t) throws SQLException;
@Override
default R apply(T t) {
try {
return applySQL(t);
} catch (SQLException e) {
throw new RuntimeException(e); // or your own unchecked exception
}
}
static <T, R> Function<T, R> adapt(SQLFunction<T, R> f) {
return f;
}
}
Then, you could use it this way:
Map<String, String> columnAndValueMap = columnName.stream()
.collect(Collectors.toMap(
Function.identity(),
SQLFunction.adapt(rs::getString)));
As @fps mentioned, the rs.getString()
method throws a SQLException as described in its signature.
Assuming you are seeking to create a map with column names as keys and result set strings as values, you can do:
List<String> columnNames = List.of("columnA", "columnB");
Map<String, Object> map = columnNames.stream().collect(
Collectors.toMap(Function.identity(), s -> {
try {
return Optional.ofNullable(rs.getString(s));
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return s;
}));
This is a bit messy since you need to catch the SQLException
during the stream operations. Further, an encouraged practice is to use Optional
since the getString()
method can return a null. (Understood that you are assuming that there will be no nulls. Your IDE may highlight the lack of Optional
as a warning.)
You may instead be better off using a simple for loop and surround it with a try/catch:
Map<String, String> map = new HashMap<>(columnNames.size());
for (String columnName : columnNames) {
try {
map.put(columnName, rs.getString(columnName));
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.