假设我有一个Oracle数据库和一个像这样的接口:
public interface DaoMapper { @Select({ "SELECT col1, col2, col3", "FROM my_table" }) List<Map<String, Object>> getUntyped(); }
如果我致电getUntyped()并且所有列均具有值,则映射包含三个条目。但是,如果col2为NULL,则地图只有两个条目。在许多情况下,这不是问题,但是在我们代码的通用部分中,我实际上想.values()在该地图上调用,并希望包含三个条目的列表。任何条目都可以是null(或一个空字符串,与Oracle中的相同)。
getUntyped()
col2
NULL
.values()
null
实际上,我真的很高兴这样的事情,其中每个外部列表都由具有三个条目的列表组成:
@Select({ "SELECT col1, col2, col3", "FROM my_table" }) List<List<Object>> getUntypedList();
但是,iBatis告诉我这是不受支持的操作。
因此,我在这里问我如何告诉iBatis包含包含NULL或为空字符串的列。
多亏了乔凡尼(Giovanni)的回答,我注意到了类型处理程序的示例,然后从那里开始:
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, ""); } }
现在的界面是:
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(); }
我应该补充一点,最大的好处是我可以在每条语句的每一列中指定它。为了更通用,最好按每个语句指定此名称。也许在将来的版本中?