灵凝睁大眼睛,心知虽然师父说得简单,其实却极为困难。青阳离火与青阳玄寒之气本就是极阳与极阴之气,还要再从中提炼出一点至阴和一点至阳,真是谈何容易,又要让这一点至阴和一点至阳互相流转,并在流转的过程中以意志强迫其逆转成象征玄无的始气,更是难上加难。

“吱嘎”方潜开着一辆白色的宝马X3停在了几人跟前,打开车窗道:“小民,两位大美女上车。”

game828官方下载最新版

他知道自己已经找出了彻底解决青阳之气在对付敌人时容易消散的办法。
“那就好!”布玛也是第一次知道赛亚人还能靠着意志在月亮之下从大猩猩变回原来的样子。

两人很快来到了丹塔之中,守卫森严的丹塔他们两个简直就是出入如无人之境,不费吹灰之力就找到了玄空子,交代了一下后便离开。

Mybatis框架解析之Builder解析


首先我们从builder这个类入手,首先我们注意到BaseBuilder,其实它的本质上市一个抽象类,它从本质上抽象出了Builder的一切,我猜想这里一定使用了建造者模式,但是这个抽象类里面居然没有抽象方法!

其中XXXValueOf方法,其实是把String字符串转换成了相对应的类型,如下代码。

  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(",")));
  }
View Code

其中resoveXXXType的目的就是把string转换成相对应的类型。

  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);
    }
  }

  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);
    }
  }

  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);
    }
  }
View Code

下面的方法是通过字符串别名解析出相对应的类型,再从类型创建实例。

 protected Object createInstance(String alias) {
    Class<?> clazz = resolveClass(alias);
    if (clazz == null) {
      return null;
    }
    try {
      return resolveClass(alias).newInstance();
    } catch (Exception e) {
      throw new BuilderException("Error creating instance. Cause: " + e, e);
    }
  }

  protected Class<?> resolveClass(String alias) {
    if (alias == null) {
      return null;
    }
    try {
      return resolveAlias(alias);
    } catch (Exception e) {
      throw new BuilderException("Error resolving class. Cause: " + e, e);
    }
  }
View Code

注意下面的,是2个不同的重载类,是第一个调用第二个。首先得到相对应的TypeHanlder类型,如果该TypeHanlder在typeHanlderRegisty注册中心有留存,那么返回,否则从javatype里创建一个新的。

protected TypeHandler<?> resolveTypeHandler(Class<?> javaType, String typeHandlerAlias) {
    if (typeHandlerAlias == null) {
      return null;
    }
    Class<?> type = resolveClass(typeHandlerAlias);
    if (type != null && !TypeHandler.class.isAssignableFrom(type)) {
      throw new BuilderException("Type " + type.getName() + " is not a valid TypeHandler because it does not implement TypeHandler interface");
    }
    @SuppressWarnings( "unchecked" ) // already verified it is a TypeHandler
    Class<? extends TypeHandler<?>> typeHandlerType = (Class<? extends TypeHandler<?>>) type;
    return resolveTypeHandler(javaType, typeHandlerType);
  }

  protected TypeHandler<?> resolveTypeHandler(Class<?> javaType, Class<? extends TypeHandler<?>> typeHandlerType) {
    if (typeHandlerType == null) {
      return null;
    }
    // javaType ignored for injected handlers see issue #746 for full detail
    TypeHandler<?> handler = typeHandlerRegistry.getMappingTypeHandler(typeHandlerType);
    if (handler == null) {
      // not in registry, create a new one
      handler = typeHandlerRegistry.getInstance(javaType, typeHandlerType);
    }
    return handler;
  }
View Code

其中MapperBuilderAssistant在此包下面,并且继承了BaseBuilder,下面对此类做一个解析,比如下面的就是解析命名空间的,就是包名。

  public String applyCurrentNamespace(String base, boolean isReference) {
    if (base == null) {
      return null;
    }
    if (isReference) {
      // is it qualified with any namespace yet?
      if (base.contains(".")) {
        return base;
      }
    } else {
      // is it qualified with this namespace yet?
      if (base.startsWith(currentNamespace + ".")) {
        return base;
      }
      if (base.contains(".")) {
        throw new BuilderException("Dots are not allowed in element names, please remove it from " + base);
      }
    }
    return currentNamespace + "." + base;
  }
View Code

下面的代码主要是用namespace得到cache的一个实例,就这么理解。

 public Cache useCacheRef(String namespace) {
    if (namespace == null) {
      throw new BuilderException("cache-ref element requires a namespace attribute.");
    }
    try {
      unresolvedCacheRef = true;
      Cache cache = configuration.getCache(namespace);
      if (cache == null) {
        throw new IncompleteElementException("No cache for namespace "" + namespace + "" could be found.");
      }
      currentCache = cache;
      unresolvedCacheRef = false;
      return cache;
    } catch (IllegalArgumentException e) {
      throw new IncompleteElementException("No cache for namespace "" + namespace + "" could be found.", e);
    }
  }
View Code

下面的方法是创建cache。

public Cache useNewCache(Class<? extends Cache> typeClass,
      Class<? extends Cache> evictionClass,
      Long flushInterval,
      Integer size,
      boolean readWrite,
      boolean blocking,
      Properties props) {
    Cache cache = new CacheBuilder(currentNamespace)
        .implementation(valueOrDefault(typeClass, PerpetualCache.class))
        .addDecorator(valueOrDefault(evictionClass, LruCache.class))
        .clearInterval(flushInterval)
        .size(size)
        .readWrite(readWrite)
        .blocking(blocking)
        .properties(props)
        .build();
    configuration.addCache(cache);
    currentCache = cache;
    return cache;
  }
View Code

其中有一个地方要弄清楚,就是Class<? extends Cache> typeClass,    Class<? extends Cache> evictionClass的区别在哪里?在哪里呢?请看下图,一个是实现,一个是装饰者,你可以暂时理解为作用不同,就这么简单。

 

下面是addParameterMap方法的一些介绍。

  public ParameterMap addParameterMap(String id, Class<?> parameterClass, List<ParameterMapping> parameterMappings) {
    
    //得到包名。
    id = applyCurrentNamespace(id, false);
    //工厂方法创建参数Map,并添加到configuration中去。
    ParameterMap parameterMap = new ParameterMap.Builder(configuration, id, parameterClass, parameterMappings).build();
    configuration.addParameterMap(parameterMap);
    return parameterMap;
  }

下面是buildParameterMap的介绍,其实它也是利用了工厂方法骑构造。

  public ParameterMapping buildParameterMapping(
      Class<?> parameterType,
      String property,
      Class<?> javaType,
      JdbcType jdbcType,
      String resultMap,
      ParameterMode parameterMode,
      Class<? extends TypeHandler<?>> typeHandler,
      Integer numericScale) {
    resultMap = applyCurrentNamespace(resultMap, true);

    // Class parameterType = parameterMapBuilder.type();
    Class<?> javaTypeClass = resolveParameterJavaType(parameterType, property, javaType, jdbcType);
    TypeHandler<?> typeHandlerInstance = resolveTypeHandler(javaTypeClass, typeHandler);

    return new ParameterMapping.Builder(configuration, property, javaTypeClass)
        .jdbcType(jdbcType)
        .resultMapId(resultMap)
        .mode(parameterMode)
        .numericScale(numericScale)
        .typeHandler(typeHandlerInstance)
        .build();
  }
View Code

下面的是建立一个结果集,然后把结果集添加到configuration里面。

  public ResultMap addResultMap(
      String id,
      Class<?> type,
      String extend,
      Discriminator discriminator,
      List<ResultMapping> resultMappings,
      Boolean autoMapping) {
    id = applyCurrentNamespace(id, false);
    extend = applyCurrentNamespace(extend, true);

    if (extend != null) {
      if (!configuration.hasResultMap(extend)) {
        throw new IncompleteElementException("Could not find a parent resultmap with id "" + extend + """);
      }
      ResultMap resultMap = configuration.getResultMap(extend);
      List<ResultMapping> extendedResultMappings = new ArrayList<ResultMapping>(resultMap.getResultMappings());
      extendedResultMappings.removeAll(resultMappings);
      // Remove parent constructor if this resultMap declares a constructor.
      boolean declaresConstructor = false;
      for (ResultMapping resultMapping : resultMappings) {
        if (resultMapping.getFlags().contains(ResultFlag.CONSTRUCTOR)) {
          declaresConstructor = true;
          break;
        }
      }
      if (declaresConstructor) {
        Iterator<ResultMapping> extendedResultMappingsIter = extendedResultMappings.iterator();
        while (extendedResultMappingsIter.hasNext()) {
          if (extendedResultMappingsIter.next().getFlags().contains(ResultFlag.CONSTRUCTOR)) {
            extendedResultMappingsIter.remove();
          }
        }
      }
      resultMappings.addAll(extendedResultMappings);
    }
    ResultMap resultMap = new ResultMap.Builder(configuration, id, type, resultMappings, autoMapping)
        .discriminator(discriminator)
        .build();
    configuration.addResultMap(resultMap);
    return resultMap;
  }
View Code

当然,下面的也太多了,就不一一介绍了,还有一些这些结果集的一些Getter方法;有兴趣的可以自己去看看,不过我们从这里得到了一个很重要的东西,那就是贯穿上下文的一个东西:Configuration!,这个东西可以说是无处不在,不管是在基类,还是在派生类中。

我们还看到了一些工厂的Relover,那这些resover类其实也是调用了上面的一些public方法而已,没啥特别的,真的。

下面我们再看看SqlSourceBuilder 这个类,这个先从string解析成map,然后再判断是否是sql类型,如果是,继续解析。

    private ParameterMapping buildParameterMapping(String content) {
      Map<String, String> propertiesMap = parseParameterMapping(content);
      String property = propertiesMap.get("property");
      Class<?> propertyType;
      if (metaParameters.hasGetter(property)) { // issue #448 get type from additional params
        propertyType = metaParameters.getGetterType(property);
      } else if (typeHandlerRegistry.hasTypeHandler(parameterType)) {
        propertyType = parameterType;
      } else if (JdbcType.CURSOR.name().equals(propertiesMap.get("jdbcType"))) {
        propertyType = java.sql.ResultSet.class;
      } else if (property == null || Map.class.isAssignableFrom(parameterType)) {
        propertyType = Object.class;
      } else {
        MetaClass metaClass = MetaClass.forClass(parameterType, configuration.getReflectorFactory());
        if (metaClass.hasGetter(property)) {
          propertyType = metaClass.getGetterType(property);
        } else {
          propertyType = Object.class;
        }
      }
      ParameterMapping.Builder builder = new ParameterMapping.Builder(configuration, property, propertyType);
      Class<?> javaType = propertyType;
      String typeHandlerAlias = null;
      for (Map.Entry<String, String> entry : propertiesMap.entrySet()) {
        String name = entry.getKey();
        String value = entry.getValue();
        if ("javaType".equals(name)) {
          javaType = resolveClass(value);
          builder.javaType(javaType);
        } else if ("jdbcType".equals(name)) {
          builder.jdbcType(resolveJdbcType(value));
        } else if ("mode".equals(name)) {
          builder.mode(resolveParameterMode(value));
        } else if ("numericScale".equals(name)) {
          builder.numericScale(Integer.valueOf(value));
        } else if ("resultMap".equals(name)) {
          builder.resultMapId(value);
        } else if ("typeHandler".equals(name)) {
          typeHandlerAlias = value;
        } else if ("jdbcTypeName".equals(name)) {
          builder.jdbcTypeName(value);
        } else if ("property".equals(name)) {
          // Do Nothing
        } else if ("expression".equals(name)) {
          throw new BuilderException("Expression based parameters are not supported yet");
        } else {
          throw new BuilderException("An invalid property "" + name + "" was found in mapping #{" + content + "}.  Valid properties are " + parameterProperties);
        }
      }
      if (typeHandlerAlias != null) {
        builder.typeHandler(resolveTypeHandler(javaType, typeHandlerAlias));
      }
      return builder.build();
    }
View Code

其中比较重要的就是下面的代码,下面做一个分析,首先会得到typeHanldler,然后再在buidler里对这个进行注册。

     if (typeHandlerAlias != null) {
        builder.typeHandler(resolveTypeHandler(javaType, typeHandlerAlias));
      }
      return builder.build();

我们关键是看看builder.build方法,它是一个private的方法,它的作用就是get到我们开始设置的值,下面的validate方法也是做一些基础验证的,具体的可以略过,没啥价值。

    private void resolveTypeHandler() {
      if (parameterMapping.typeHandler == null && parameterMapping.javaType != null) {
        Configuration configuration = parameterMapping.configuration;
        TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
        parameterMapping.typeHandler = typeHandlerRegistry.getTypeHandler(parameterMapping.javaType, parameterMapping.jdbcType);
      }
    }

下面我们再来看看这个类:StaticSqlSource 其实我觉得这个玩意没啥用!真的不是贬低写mybatis的人,真没看出有什么用,具体看下面的代码。

public class StaticSqlSource implements SqlSource {

  private final String sql;
  private final List<ParameterMapping> parameterMappings;
  private final Configuration configuration;

  public StaticSqlSource(Configuration configuration, String sql) {
    this(configuration, sql, null);
  }

  public StaticSqlSource(Configuration configuration, String sql, List<ParameterMapping> parameterMappings) {
    this.sql = sql;
    this.parameterMappings = parameterMappings;
    this.configuration = configuration;
  }

  @Override
  public BoundSql getBoundSql(Object parameterObject) {
    return new BoundSql(configuration, sql, parameterMappings, parameterObject);
  }
View Code

这些类同级的包里面,还有一个XML的包,里面包含的DTD文件,以及一些工具类,大家理解这些东西,其实就是为了把烦人的XML转换成一个可用的configuration对象的的工具类就行了,真的没必要深究。

关于builder的annotation 大家应该不陌生了吧?我介绍了这么多。构造函数说得很清楚了,其实把一些基本的注解加进了,CRUD而已。

  public MapperAnnotationBuilder(Configuration configuration, Class<?> type) {
    String resource = type.getName().replace(".", "/") + ".java (best guess)";
    this.assistant = new MapperBuilderAssistant(configuration, resource);
    this.configuration = configuration;
    this.type = type;

    sqlAnnotationTypes.add(Select.class);
    sqlAnnotationTypes.add(Insert.class);
    sqlAnnotationTypes.add(Update.class);
    sqlAnnotationTypes.add(Delete.class);

    sqlProviderAnnotationTypes.add(SelectProvider.class);
    sqlProviderAnnotationTypes.add(InsertProvider.class);
    sqlProviderAnnotationTypes.add(UpdateProvider.class);
    sqlProviderAnnotationTypes.add(DeleteProvider.class);
  }
View Code

有一个核心方法,比较重要:parse,作用很明显,就是转换呗,然后是从configuration拿玩意,然后转换成有用的东西。其实这个不就是我们写的mapper类的XML文件吗?!用过mybatis的人都知道的。注释写了一点,不过更深入了,我觉得没必要写了,靠大家自己去发掘。

  public void parse() {
    String resource = type.toString();
    if (!configuration.isResourceLoaded(resource)) {
      //载入XML资源文件。
      loadXmlResource();
      
      //把资源文件添加到configuation里面。
      configuration.addLoadedResource(resource);
      assistant.setCurrentNamespace(type.getName());
      //修改assistant变量
      parseCache();
      //修改assistant变量2
      parseCacheRef();
      Method[] methods = type.getMethods();
      for (Method method : methods) {
        try {
          // issue #237
          if (!method.isBridge()) {
            parseStatement(method);
          }
        } catch (IncompleteElementException e) {
          configuration.addIncompleteMethod(new MethodResolver(this, method));
        }
      }
    }
    parsePendingMethods();
  }
View Code

 

当前文章:http://hnhdqp.com/forum.php?mod=viewthread&tid=54569

发布时间:2019-01-23 15:18:49

斗牛棋牌怎么玩 冀友棋牌作弊器在哪下 集结号捕鱼游戏充值 金陵热线棋牌游戏大厅下载 怎么下载联众大厅 六博棋牌南充 扑克三公出千视频 街机捕鱼2赢话费

编辑:扁董马顺

相关新闻

榆林市教育局所属高中公开引进高层次人才(教师)公告

2019-01-23 09:12:17

曲靖虏级戎电子科技有限公司

澳大利亚现燃烧UFO从天而降 产生巨大爆炸

2019-01-23 16:42:48

德州盟牢铣集团公司

佳县积极改善农村生产生活条件

2019-01-23 18:57:33

鄢陵蕉暗檀信息技术有限公司

荣事达热水器 人性化需求开启舒适热水生活

2019-01-23 14:50:43

雅安庞烙蘸经贸有限公司

热门推荐

  • 乐视网:去年归属股东的净利润为-16.52亿元,较上年减少435.02%
  • 吃鸡党的功劳!Steam同时在线人数破1800万
  • 中国毕节农产品区域公共品牌论坛召开 
  • 双12戴尔大促:全系列笔记本直降,最高优惠4000元
  • 俄通过“外国代理人”条款修订案 反制美制裁俄电视台
  • 美女COS死亡之翼版D.Va:灭世者黑皮肤帅爆
  • 四川女子公招复试被拒录:自考法律专业不属法学类
  • 西数拒绝东芝要求:称不会放行出售芯片交易换取投资权
  • 美女老板月收入从5000到20000,实现翻4倍的过程经历
  • 四川茂县救援现场发生二次垮塌 连续1分钟
  • 河北新闻网版权所有 本站点信息未经允许不得复制或镜像 法律顾问:快来台州麻将还能玩吗 七星耒阳字牌
  • 蔚蓝棋牌游戏 copyright ? 2000 - 2016
  • 新闻热线:0311-67563366 广告热线:0311-67562966 新闻投诉:0311-67562994
  • 冀ICP备 09047539号-1 | 互联网新闻信息服务许可证编号:1312006002
  • 广播电视节目制作经营许可证(冀)字第101号|信息网络传播视听节目许可证0311618号
  • 星月棋牌苹果官网下载 熊猫麻将怎样充房卡 友闲棋牌透视免费版 棋牌游戏热门推荐