Mybatis源码--BaseBuilder源码分析

1 概述

BaseBuilder家族的主要作用就是处理配置文件的内容,包括mapper配置文件和config文件,在这里我们有必要首先对其基类进行简单地说明。

2 属性

2.1 configuration

持有配置文件对象,方便解析配置文件后对数据进行设置。

2.2 typeAliasRegistry

类别名注册器,里面持有类别名和类的键值对。

2.3 typeHandlerRegistry

类型处理注册器。我们来看一下类型处理注册器里面的详细实现。

2.3.1 属性

//JDBC类型和类型处理器的映射关系,这里用到EnumMap,这个EnumMap的键必须是枚举类中的值
private final Map<JdbcType, TypeHandler<?>> JDBC_TYPE_HANDLER_MAP = new EnumMap<JdbcType, TypeHandler<?>>(JdbcType.class);

//类,JDBC类型和类型处理器的映射关系
private final Map<Type, Map<JdbcType, TypeHandler<?>>> TYPE_HANDLER_MAP = new HashMap<Type, Map<JdbcType, TypeHandler<?>>>();

//如果类没有对应的类型处理器就是用这个类型处理器
private final TypeHandler<Object> UNKNOWN_TYPE_HANDLER = new UnknownTypeHandler(this);

//普通类和类型处理器的映射关系
private final Map<Class<?>, TypeHandler<?>> ALL_TYPE_HANDLERS_MAP = new HashMap<Class<?>, TypeHandler<?>>();

2.3.2 核心函数

(1) java type + handler

public <T> void register(Class<T> javaType, TypeHandler<? extends T> typeHandler) {
    register((Type) javaType, typeHandler);
}

我们可以看见这个函数里面将javaType进行向上转型成Type类型后,然后调用了另一个函数。

private <T> void register(Type javaType, TypeHandler<? extends T> typeHandler) {
	
	//获取handler对应的注解MappedJdbcTypes,这个注解标记了类型处理器对应的jdbcType
    MappedJdbcTypes mappedJdbcTypes = typeHandler.getClass().getAnnotation(MappedJdbcTypes.class);
    if (mappedJdbcTypes != null) {
		
	  //遍历jdbcType数组,进行jdbc类型,java类型和类型处理器注册	
      for (JdbcType handledJdbcType : mappedJdbcTypes.value()) {
        register(javaType, handledJdbcType, typeHandler);
      }
	  
	  //空类型注册
      if (mappedJdbcTypes.includeNullJdbcType()) {
        register(javaType, null, typeHandler);
      }
    } else {
      register(javaType, null, typeHandler);
    }
  }

可以看出来,最终都是调用了如下函数:

private void register(Type javaType, JdbcType jdbcType, TypeHandler<?> handler) {
    if (javaType != null) {
		
	  //获取java类型对应的jdbc类型和类型处理器	
      Map<JdbcType, TypeHandler<?>> map = TYPE_HANDLER_MAP.get(javaType);
      if (map == null) {
        map = new HashMap<JdbcType, TypeHandler<?>>();
		
		//添加java类型和类型处理器的映射关系
        TYPE_HANDLER_MAP.put(javaType, map);
      }
	  
	  //添加jdbc类型和类型处理器的映射关系
      map.put(jdbcType, handler);
    }
	
	//添加类型处理的类和类型处理器映射关系
    ALL_TYPE_HANDLERS_MAP.put(handler.getClass(), handler);
  }

 (2) jdbcType + handler

public void register(JdbcType jdbcType, TypeHandler<?> handler) {
    JDBC_TYPE_HANDLER_MAP.put(jdbcType, handler);
  }

这个函数其实就是直接将jdbc类型和类型处理器的map中加入映射关系。
其余的函数我们这里就不进行进一步分析了,大同小异。

3 函数

上面我们分析了BaseBuilder的属性,现在我们针对重要的函数进行分析。

3.1 将字符串转换成对应的数据类型

protected Pattern parseExpression(String regex, String defaultValue) {
    return Pattern.compile(regex == null ? defaultValue : regex);
  }

  protected Boolean booleanValueOf(String value, Boolean defaultValue) {
    return value == null ? defaultValue : Boolean.valueOf(value);
  }

  protected Integer integerValueOf(String value, Integer defaultValue) {
    return value == null ? defaultValue : Integer.valueOf(value);
  }

  protected Set<String> stringSetValueOf(String value, String defaultValue) {
    value = (value == null ? defaultValue : value);
    return new HashSet<String>(Arrays.asList(value.split(",")));
  } 

3.2 根据别名获取对应的jdbc类型

protected JdbcType resolveJdbcType(String alias) {
    if (alias == null) {
      return null;
    }
    try {
      return JdbcType.valueOf(alias);
    } catch (IllegalArgumentException e) {
      throw new BuilderException("Error resolving JdbcType. Cause: " + e, e);
    }
  }

3.3 根据别名获取结果集类型

protected ResultSetType resolveResultSetType(String alias) {
    if (alias == null) {
      return null;
    }
    try {
      return ResultSetType.valueOf(alias);
    } catch (IllegalArgumentException e) {
      throw new BuilderException("Error resolving ResultSetType. Cause: " + e, e);
    }
  }

3.4 根据别名获取参数类型

protected ParameterMode resolveParameterMode(String alias) {
    if (alias == null) {
      return null;
    }
    try {
      return ParameterMode.valueOf(alias);
    } catch (IllegalArgumentException e) {
      throw new BuilderException("Error resolving ParameterMode. Cause: " + e, e);
    }
  }

 我们查看ParameterMode枚举类,可以看见参数类型有 IN, OUT, INOUT。
 针对余下的函数这里就不详细说明了,其实就是调用其属性对应的函数。

后面继续更新对Mybatis源码的分析,欢迎交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值