0%

Mybatis源码 Parameters JDBC Type

Mybatis Parameters JDBC Type

Mybatis的sqlmap中Parameters的jdbcType参数可以不设置,Parameters 官方文档中解释:

The JDBC Type is required by JDBC for all nullable columns, if null is passed as a value. You can investigate this yourself by reading the JavaDocs for the PreparedStatement.setNull() method.

Mybatis在处理参数具体类型时从TypeHandlerRegistry中获取具体的TypeHandler。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* parameter where子句后具体某个参数入参
* jdbcType sqlmap中声明的jdbcType,如:where id = #{id,jdbcType=VARCHAR}
**/
private TypeHandler<? extends Object> resolveTypeHandler(Object parameter, JdbcType jdbcType) {
TypeHandler<? extends Object> handler;
if (parameter == null) {
handler = OBJECT_TYPE_HANDLER;
} else {
//参数的运行时类型
handler = typeHandlerRegistry.getTypeHandler(parameter.getClass(), jdbcType);
if (handler == null || handler instanceof UnknownTypeHandler) {
handler = OBJECT_TYPE_HANDLER;
}
}
return handler;
}

private <T> TypeHandler<T> getTypeHandler(Type type, JdbcType jdbcType) {
//TYPE_HANDLER_MAP是jdbc类型到java数据类型映射,详见下图
//TYPE_HANDLER_MAP中每个类型都会包含类似这条记录"null" -> "class java.lang.Float"(null为key->java类型为value)
//也就是说只要入参运行时类型确定,handler就确定
Map<JdbcType, TypeHandler<?>> jdbcHandlerMap = TYPE_HANDLER_MAP.get(type);
TypeHandler<?> handler = null;
//该步一定会拿到handler,除非参数类型Mybatis本身处理不了,并且没有自定义的handler
if (jdbcHandlerMap != null) {
handler = jdbcHandlerMap.get(jdbcType);
if (handler == null) {
handler = jdbcHandlerMap.get(null);
}
}
if (handler == null && type != null && type instanceof Class && Enum.class.isAssignableFrom((Class<?>) type)) {
handler = new EnumTypeHandler((Class<?>) type);
}
// type drives generics here
return (TypeHandler<T>) handler;
}

插图1

继续看了mysql.jdbc对null值的处理,发现其实这个jdbcType在设置值时根本没用到,可能是为了以后使用吧。直接上代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* Set a parameter to SQL NULL
*
* <p>
* <B>Note:</B> You must specify the parameters SQL type (although MySQL
* ignores it)
* </p>
*
* @param parameterIndex
* the first parameter is 1, etc...
* @param sqlType
* the SQL type code defined in java.sql.Types
*
* @exception SQLException
* if a database access error occurs
*/
public void setNull(int parameterIndex, int sqlType) throws SQLException {
synchronized (checkClosed().getConnectionMutex()) {
setInternal(parameterIndex, "null"); //$NON-NLS-1$
this.isNull[parameterIndex - 1 + getParameterIndexOffset()] = true;

this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.NULL;
}
}

小生不才,以上如有描述有误的地方还望各位不吝赐教 !^_^!