Let's say I have an Oracle database and an interface like this:
public interface DaoMapper {
@Select({
"SELECT col1, col2, col3",
"FROM my_table" })
List<Map<String, Object>> getUntyped();
}
If I call getUntyped()
and all columns have a value the map contains three entries. However, if col2
is NULL
, the map has only two entries. In many cases this isn't a problem, but in a generic part of our code I actually want to call .values()
on that map and want a list consisting of three entries. Any entry may be null
(or an empty string as that's the same in Oracle).
Actually, what I would be really happy about is something like this where each outer list consists of lists with three entries:
@Select({
"SELECT col1, col2, col3",
"FROM my_table" })
List<List<Object>> getUntypedList();
However, iBatis tells me that this is an unsupported operation.
Therefore, I'm here to ask how I can tell iBatis to include columns that are NULL
or an empty string.
Thanks to Giovanni's answer I noticed the example for type handlers and went from there:
public class EmptyStringTypeHandler extends StringTypeHandler {
@Override
public String getResult(ResultSet rs, String columnName) throws SQLException {
return unnulledString(super.getResult(rs, columnName));
}
@Override
public String getResult(ResultSet rs, int columnIndex) throws SQLException {
return unnulledString(super.getResult(rs, columnIndex));
}
@Override
public String getResult(CallableStatement cs, int columnIndex) throws SQLException {
return unnulledString(super.getResult(cs, columnIndex));
}
private String unnulledString(String value) {
return StringUtils.defaultString(value, "");
}
}
The interface is now:
public interface DaoMapper {
@Select({
"SELECT col1, col2, col3",
"FROM my_table" })
@Results(value = {
@Result(column = "col1", property = "col1", typeHandler = EmptyStringTypeHandler.class),
@Result(column = "col2", property = "col2", typeHandler = EmptyStringTypeHandler.class),
@Result(column = "col3", property = "col3", typeHandler = EmptyStringTypeHandler.class)
})
List<LinkedHashMap<String, ?>> getUntyped();
}
I should add that the big advantage is that I can specify this per column per statement. For more generic use it would be better to specify this per statement. Maybe in some future version?