背景
自己拼接一个 sql ,然后将其交给 mybatis mapper ,返回 Map<String,Object> ,也就是说我不知道查询到的列对应的 javaType,但是我希望 datetime 类型返回的值是格式化后的,如 2011-11-12 12:12:00
调查过程
- 查找
typeHandler逻辑
下面的类是在org.apache.ibatis.executor.resultset.DefaultResultSetHandler.java
image.png
从执行逻辑看,根据javaType=Object,jdbcType=TimeStamp并没有找到合适的typeHandler,最后使用了处理空值的typeHandler,也即UnknownTypeHandler,然后执行到下面的逻辑时,会判断如果使用的是UnknownTypeHandler,则根据jdbcType再去查找有没有对应的合适的javaType,这时候找到了将javaType重新调整为了class java.sql.Timestamp,然后继续上面的查询逻辑,继续查找typeHandler,这次找到的typeHandler是SqlTimestampTypeHandler。
下面的方法是在类org.apache.ibatis.executor.resultset.ResultSetWrapper.java
image.png
这时候我们知道可以通过注册一个处理javaType=Object,jdbcType=TimeStamp的typeHandler,来格式化查询后的日期。
实现TypeHandler:
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.*;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author baizhizhen
*/
public class DateFormatTypeHandler extends BaseTypeHandler<String> {
private DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
throws SQLException {
try {
ps.setTimestamp(i, new Timestamp((format.parse(parameter)).getTime()));
} catch (ParseException e) {
e.printStackTrace();
}
}
@Override
public String getNullableResult(ResultSet rs, String columnName)
throws SQLException {
Timestamp sqlTimestamp = rs.getTimestamp(columnName);
if (sqlTimestamp != null) {
Date date = new Date(sqlTimestamp.getTime());
return format.format(date);
}
return null;
}
@Override
public String getNullableResult(ResultSet rs, int columnIndex)
throws SQLException {
Timestamp sqlTimestamp = rs.getTimestamp(columnIndex);
if (sqlTimestamp != null) {
Date date = new Date(sqlTimestamp.getTime());
return format.format(date);
}
return null;
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
Timestamp sqlTimestamp = cs.getTimestamp(columnIndex);
if (sqlTimestamp != null) {
Date date = new Date(sqlTimestamp.getTime());
return format.format(date);
}
return null;
}
}
注册 typeHandler:
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
typeHandlerRegistry.register(Object.class,JdbcType.TIMESTAMP,new DateFormatTypeHandler());
一切OK了。










网友评论