我一直在尝试在MyBatis中创建自定义TypeHandler
,以便对于数据库中的null
列,MyBatis返回Null Object pattern的实现,而不是{{1}在域类中。
在谷歌搜索寻求帮助之后,我找到了一个优秀的项目mybatis-koans,即koan 19,它使用我正在使用的相同方法解决了这个问题,即扩展{ {1}}(是抽象的)。此时,我有一个与EmailTypeHandler
in that koan类似的具体null
:
BaseTypeHandler<T>
不幸的是,似乎作者( midpeter444 )面临同样的问题:当数据库中的值为TypeHandler
时,仍会返回null而不是在具体/**
* Acts as a factory method to return the appropriate implementation of an Email.
* Returns a Null object if the email value in the database was null/empty
*/
public class EmailTypeHandler extends BaseTypeHandler<Email> {
@Override
public Email getNullableResult(ResultSet rs, String colName) throws SQLException {
return createEmail(rs.getString(colName));
}
@Override
public Email getNullableResult(ResultSet rs, int colNum) throws SQLException {
return createEmail(rs.getString(colNum));
}
private Email createEmail(String s) {
System.out.println(s);
if (s == null || s.equals("")) {
return new NullEmail();
} else {
return new EmailImpl(s);
}
}
@Override
public Email getNullableResult(CallableStatement arg0, int arg1) throws SQLException {
return null;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int colNum,
Email e, JdbcType t) throws SQLException {
}
}
。
答案 0 :(得分:3)
我在发布问题后立即看到了解决方案。在BaseTypeHandler代码中:
[...]
public T getResult(ResultSet rs, String columnName) throws SQLException {
T result = getNullableResult(rs, columnName);
if (rs.wasNull()) {
return null;
} else {
return result;
}
}
public T getResult(ResultSet rs, int columnIndex) throws SQLException {
T result = getNullableResult(rs, columnIndex);
if (rs.wasNull()) {
return null;
} else {
return result;
}
}
public T getResult(CallableStatement cs, int columnIndex) throws SQLException {
T result = getNullableResult(cs, columnIndex);
if (cs.wasNull()) {
return null;
} else {
return result;
}
}
public abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
public abstract T getNullableResult(ResultSet rs, String columnName) throws SQLException;
public abstract T getNullableResult(ResultSet rs, int columnIndex) throws SQLException;
public abstract T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException;
[...]
显然,当数据库中的值为BaseTypeHandler
时,null
将返回null
,在这种情况下,cs.WasNull()
为true
。因此,解决方案是创建一个具体的TypeHandler<T>
返回适当的实现(在这种情况下,当数据库中的值为null时为NullObject implmentation),而不继承BaseTypeHandler
。
已编辑(以下是 quux00 的评论):当然,我们可以覆盖getResult
的{{1}}方法,因为该功能方法BaseTypeHandler
提供的方法很有用。
答案 1 :(得分:2)
感谢您的回答!它帮助我理解了我的问题以及如何克服它。我希望结果永远不会为空。
通过发布BaseTypeHandler
的代码,它确认根据ResultSet.wasNull
返回null,而不是getNullableResult
返回的结果本身。所以我在getResult
的具体子类中覆盖了BaseTypeHandler
。在getResult
的自定义实现中,调用super.getResult
,然后检查null。以下是一个例子:
public Money getResult ( ResultSet rs, String columnName ) throws SQLException
{
Money result = super.getResult ( rs, columnName );
return result == null ? Money.ZERO : result;
}
public Money getResult ( ResultSet rs, int columnIndex ) throws SQLException
{
Money result = super.getResult ( rs, columnIndex );
return result == null ? Money.ZERO : result;
}
public Money getResult ( CallableStatement cs, int columnIndex ) throws SQLException
{
Money result = super.getResult ( cs, columnIndex );
return result == null ? Money.ZERO : result;
}