T getResult(ResultSet rs, int columnIndex) throws SQLException;
T getResult(CallableStatement cs, int columnIndex) throws SQLException;
}
我们可以看到这个接口中定义的两类方法分别是
-
setParameter 对占位符赋值
-
getResult 根据字段获取值
2.BaseTypeHandler
为了方便用户自定义TypeHandler的实现,在MyBatis中提供了BaseTypeHandler这个抽象类,它实现了TypeHandler接口,并继承了TypeReference类,
在BaseTypeHandler中的实现方法中实现了对null的处理,非空的处理是交给各个子类去实现的。这个在代码中很清楚的体现了出来. — 代码有简化,方便查看
@Override
public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
if (parameter == null) {
// 简化了代码 如果参数为空就设置 null
ps.setNull(i, jdbcType.TYPE_CODE);
} else {
// 省略 try 语句 参数不为空就调用子类的实现
setNonNullParameter(ps, i, parameter, jdbcType);
}
}
@Override
public T getResult(ResultSet rs, String columnName) throws SQLException {
return getNullableResult(rs, columnName);
}
@Override
public T getResult(ResultSet rs, int columnIndex) throws SQLException {
return getNullableResult(rs, columnIndex);
}
@Override
public T getResult(CallableStatement cs, int columnIndex) throws SQLException {
return getNullableResult(cs, columnIndex);
}
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;
3.TypeHandler实现类
TypeHandler的实现类比较多,而且实现也都比较简单。
以Integer为例
/**
- @author Clinton Begin
*/
public class IntegerTypeHandler extends BaseTypeHandler {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Integer parameter, JdbcType jdbcType)
throws SQLException {
ps.setInt(i, parameter); // 实现参数的绑定
}
@Override
public Integer getNullableResult(ResultSet rs, String columnName)
throws SQLException {
int result = rs.getInt(columnName); // 获取指定列的值
return result == 0 && rs.wasNull() ? null : result;
}
@Override
public Integer getNullableResult(ResultSet rs, int columnIndex)
throws SQLException {
int result = rs.getInt(columnIndex); // 获取指定列的值
return result == 0 && rs.wasNull() ? null : result;
}
@Override
public Integer getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
int result = cs.getInt(columnIndex); // 获取指定列的值
return result == 0 && cs.wasNull() ? null : result;
}
}
4.TypeHandlerRegistry
通过前面的介绍我们发现在MyBatis中给我们提供的具体的类型转换器实在是太多了,那么在实际的使用时我们是如何知道使用哪个转换器类处理的呢?实际上再MyBatis中是将所有的TypeHandler都保存注册在了TypeHandlerRegistry中的。首先注意声明的相关属性
// 记录JdbcType和TypeHandle的对应关系
private final Map<JdbcType, TypeHandler<?>> jdbcTypeHandlerMap = new EnumMap<>(JdbcType.class);
// 记录Java类型向指定的JdbcType转换时需要使用到的TypeHandle