MyBatis源码通~SqlSourceBuilder

    xiaoxiao2021-04-15  238

    SqlSourceBuilder

    两个作用:

    将"#{xxx}“替换为占位符”?"将占位符"?"对应的属性信息一起构建成到ParameterMapping中,以便在后续ParameterHandler真正地参数赋值。

    源码解析

    先分析从SqlNode 上下文中得到完成的originalSql,将其中的"#{xxx}“替换为占位符”?"同时为每个"#{xxx}"对应的属性构建对应的ParameterMapping对象。进一步得到一个包含?的完整的SQL语句,最后构建出一个StaticSqlSource对象。 //☆☆--SqlSourceBuilder //从SqlNode 上下文中得到完成的originalSql后开始构建SqlSource public SqlSource parse(String originalSql, Class<?> parameterType, Map<String, Object> additionalParameters) { //SqlSourceBuilder静态内部类,用于占位符替换和构建ParameterMapping ParameterMappingTokenHandler handler = new ParameterMappingTokenHandler(configuration, parameterType, additionalParameters); GenericTokenParser parser = new GenericTokenParser("#{", "}", handler); //NOTE: 将#{}替换为占位符? String sql = parser.parse(originalSql); //最后构建StaticSqlSource return new StaticSqlSource(configuration, sql, handler.getParameterMappings()); } ParameterMappingTokenHandler //☆☆--SqlSourceBuilder.ParameterMappingTokenHandler private static class ParameterMappingTokenHandler extends BaseBuilder implements TokenHandler { //记录所有占位符对应的ParameterMapping private List<ParameterMapping> parameterMappings = new ArrayList<>(); //占位符替换 public String handleToken(String content) { parameterMappings.add(buildParameterMapping(content)); return "?"; } //构建ParameterMapping 包含每个占位符属性的信息,如:jdbcType、javaType、typeHandler、property等等 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 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 (typeHandlerAlias != null) { builder.typeHandler(resolveTypeHandler(javaType, typeHandlerAlias)); } return builder.build(); } }

    最新回复(0)