ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

myBatis源码解析-类型转换篇

2020-11-07 20:03:04  阅读:244  来源: 互联网

标签:类型转换 939761500 search manhua keyword 源码 https myBatis com


开始分析Type包前,说明下使用场景。数据构建语句使用PreparedStatement,需要输入的是jdbc类型,但我们一般写的是java类型。同理,数据库结果集返回的是jdbc类型,而我们需要java类型。这就涉及到一个类型转换问题,Type包就是解决这个问题。下面是Type包类图所在结构:

源码解析

  1. BaseTypeHandle - 类型处理器实现的基类

mybatis中的默认类型处理器,自定义类型处理器都继承自BaseTypeHandle。是分析类型处理器的关键,查看其类图如下:

分析BaseTypeHandle前,分析其接口TypeHandle。

复制代码
// 类型处理器接口,查询参数时将java类型转为jdbc类型。获取结果时将jdbc类型转问java类型。
public interface TypeHandler {
// 设置查询参数,java类型转为jdbc类型
void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
// 获取结果参数,jdbc转为java类型
T getResult(ResultSet rs, String columnName) throws SQLException;

T getResult(ResultSet rs, int columnIndex) throws SQLException;

T getResult(CallableStatement cs, int columnIndex) throws SQLException;

}
复制代码
TypeHandler接口定义了参数转换的方法。查询时将java类型转为jdbc类型,获取结果时将jdbc类型转为java类型。

分析继承的抽象类,TypeReference,主要是获取泛型T的原生类型。

复制代码
public abstract class TypeReference {

private final Type rawType; // 保存所处理的java原生类型、个人理解即T泛型的类型。

protected TypeReference() {
rawType = getSuperclassTypeParameter(getClass());
}
// rawType的获取过程。任务类型处理器都需要继承BaseTypeHandle,而BaseTypeHandle继承TypeReference,此处为了获取T的java类型。
// 至于为什么使用这一变量,因为我们自定义类型处理器可以不指定java类型,只指定jdbc类型,这样java类型默认就是T类型。
Type getSuperclassTypeParameter(Class<?> clazz) {
Type genericSuperclass = clazz.getGenericSuperclass(); // 获取分类,包括T。此处和getSuperClass的区别是,getSuperClass只返回直接父类,并不包括父类带的泛型T
if (genericSuperclass instanceof Class) { // 任何类型处理器都有泛型T,一直循环找,如果没找到,直接报错。
// try to climb up the hierarchy until meet something useful
if (TypeReference.class != genericSuperclass) {
return getSuperclassTypeParameter(clazz.getSuperclass());
}
https://www.iqiyi.com/manhua/search-keyword=乐昌哪儿有捐卵地方?微信939761500
https://www.iqiyi.com/manhua/search-keyword=乐昌公司高薪直招捐卵女孩微信939761500
https://www.iqiyi.com/manhua/search-keyword=乐昌公司高薪直招捐卵志愿者微信939761500
https://www.iqiyi.com/manhua/search-keyword=乐昌招聘捐卵微信微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄招捐卵女孩微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄我要捐卵微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵中介微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄靠谱捐卵中介微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵机构微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄高补偿捐卵微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄哪里可以捐卵微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵服务微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵拿多少钱微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵子微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵的价格微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵营养费微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵中心微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄卵子库微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵补偿微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄有偿捐卵微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄爱心捐卵微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵联系方式微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵能拿多少钱微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵一般多少钱微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄大学生捐卵微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄欠网贷捐卵微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵要求微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄高薪招聘捐卵中心微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵志愿者微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄哪里捐卵补偿高微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵需要多长时间微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄怎么捐卵 微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄哪里有捐卵的 微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄我要捐卵 微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄爱心捐卵 微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄哪里有捐卵 微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄怎样捐卵 微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄个人捐卵 微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵多少钱 微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵群 微信939761500
throw new TypeException("'" + getClass() + "' extends TypeReference but misses the type parameter. "
+ "Remove the extension or add a type parameter to it.");
}

Type rawType = ((ParameterizedType) genericSuperclass).getActualTypeArguments()[0]; // 获取泛型T的java类型
// TODO remove this when Reflector is fixed to return Types
if (rawType instanceof ParameterizedType) {  // ?自己debug没有进入到这一步,保留。个人理解是万一还是类型嵌套模式如user<T>,还有泛型T。就再次获取T的java类型。
  rawType = ((ParameterizedType) rawType).getRawType();
}

return rawType;

}

public final Type getRawType() {
return rawType; // 返回解析的rawType
}
.....
}
复制代码
TypeReference类提供了获取rawType的方法。对于我们自定义类型转换器,可以只输入要转换的jdbc类型,那默认的待转换java类型就是rawType类型。

接下来分析BaseTypeHandle,也是一个抽象类,查看其源码,主要实现了对输入参数,结果参数为空的处理,若不为空,则交给子类具体实现。

复制代码
// 类型处理器基类,增加了输入参数为null时的处理
public abstract class BaseTypeHandler extends TypeReference implements TypeHandler {

protected Configuration configuration; // 全局配置参数

public void setConfiguration(Configuration c) {
this.configuration = c;
}

public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
if (parameter == null) { // 对输入参数为null时的处理
if (jdbcType == null) { // jdbcType不能为空
throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters.");
}
try {
ps.setNull(i, jdbcType.TYPE_CODE); // 将指定位置参数设置为空
} catch (SQLException e) {
throw new TypeException("Error setting null for parameter #" + i + " with JdbcType " + jdbcType + " . " +
"Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. " +
"Cause: " + e, e);
}
} else {
setNonNullParameter(ps, i, parameter, jdbcType); // 输入参数不为空的处理
}
}
.......
// 对非空参数需要子类实现。
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其实只对空数据进行处理,非空数据交给子类实现,此处使用了模板设计模式。查看具体的类型处理器,如DateTypeHandle进行验证。

复制代码
public class DateTypeHandler extends BaseTypeHandler { // 日期转换处理器,泛型T为java.util.date

@Override
public void setNonNullParameter(PreparedStatement ps, int i, Date parameter, JdbcType jdbcType)
throws SQLException {
ps.setTimestamp(i, new Timestamp((parameter).getTime())); // 设置PreparedStatement,其实就是java类型转为数据库识别的jdbc类型
}
https://www.iqiyi.com/manhua/search-keyword=南雄有偿招募捐卵 微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵吧 微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵志愿者 微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵流程 微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵一次多少钱微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄哪里可以捐卵高价微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵可以拿多少钱微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄哪里可以捐卵微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵一般多少钱微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵价格微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵多少钱微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄哪里能捐卵微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄正规捐卵得多少钱微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵联系方式微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄有偿捐卵中心微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄有偿捐卵联系招聘微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄哪里有正规捐卵微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄招聘捐卵女孩微信微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄招聘捐卵多少钱微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵补偿价格表微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄的捐卵中介靠谱吗?微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄哪里有捐卵公司微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄哪里捐卵价格高微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄卖卵子联系方式微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄正规医院捐卵子多少钱微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄招聘捐卵微信群微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄招代妈捐卵女孩捐卵群微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄高薪招聘捐卵女孩微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄有偿捐卵女孩联系方式微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄正规捐卵微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄高薪招聘捐卵女孩志愿者微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄有招捐卵的吗?微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵对身体有影响吗?微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵补偿多少?捐卵可以拿多少钱?微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵有多少钱?哪里可以捐?微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄有哪些正规医院可以捐卵?微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄捐卵需要几天微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄哪里可以找到捐卵志愿者?微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄可以捐卵的医院在哪里微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄有哪些正规医院可以捐卵微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄哪里可以捐卵?微信939761500
https://www.iqiyi.com/manhua/search-keyword=南雄要去哪里捐呢?微信939761500
@Override
public Date getNullableResult(ResultSet rs, String columnName)
throws SQLException {
Timestamp sqlTimestamp = rs.getTimestamp(columnName); // 获取指定列的结果
if (sqlTimestamp != null) {
return new Date(sqlTimestamp.getTime()); // 获取Date结果,jdbc类型转为java类型。
}
return null;
}
复制代码
类型处理器实现也很简单,是将java数据类型和数据库识别的jdbc类型的相互转换。其余的类型处理器太多了,暂且不分析了,大家感兴趣的可以自己看下。

  1. TypeHandleRegistry - 类型处理器注册类

类型转换处理器定义完毕后,需要有个仓库进行注册,后续使用直接去拿即可。TypeHandleRegistry就是处理器注册的地方。现在对TypeHandleRegistry源码进行分析。

复制代码
private static final Map<Class, Class> reversePrimitiveMap = new HashMap<Class, Class>() {
private static final long serialVersionUID = 1L;
{
put(Byte.class, byte.class);
put(Short.class, short.class);
put(Integer.class, int.class);
put(Long.class, long.class);
put(Float.class, float.class);
put(Double.class, double.class);
put(Boolean.class, boolean.class);
put(Character.class, char.class);
}
};
// 数据库类型处理器map集合,jdbc类型为key,TypeHandle为value
private final Map<JdbcType, TypeHandler> JDBC_TYPE_HANDLER_MAP = new EnumMap<jdbctype, typehandler<?="">>(JdbcType.class);
// java类型处理器map集合,由此可知,一个java类型可以对应对个 jdbc类型
private final Map<Type, Map<JdbcType, TypeHandler>> TYPE_HANDLER_MAP = new HashMap<type, map<jdbctype,="" typehandler<?="">>>();
// 默认的未知类型处理器
private final TypeHandler

标签:类型转换,939761500,search,manhua,keyword,源码,https,myBatis,com
来源: https://www.cnblogs.com/jas19791/p/13942116.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有