我一直试图在MyBatis中创建自定义的TypeHandler
,以便对于数据库中的null
列,MyBatis返回Null Object pattern的实现,而不是在域类中使用null
。
在寻求帮助后,我到达了一个出色的项目mybatis-koans,即koan 19,它以与我使用的相同方法(即扩展BaseTypeHandler<T>
(抽象))正好解决了这个问题。在这一点上,我有一个类似于 TypeHandler
in that koan的具体EmailTypeHandler
:
/**
* 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 {
}
}
不幸的是,似乎作者(midpeter444)面临着同样的问题:当数据库中的值为
null
时,仍然返回null而不是在具体的TypeHandler
中制作的对象。 最佳答案
发布问题后,我立即看到了解决方案。在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
。因此,解决方案是创建一个返回适当的实现(在这种情况下,当数据库中的值为null时为NullObject实现)的具体 TypeHandler<T>
,而不子类化BaseTypeHandler
。编辑后的(遵循quux00的注释):当然,我们可以重写
getResult
的BaseTypeHandler
方法,因为它的setParameters
方法提供的功能可能会有用。关于java - 具有MyBatis TypeHandler的空对象模式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14874547/