ybatis 결과 세트가 자동으로 매핑되는 인스턴스 코드

ybatis를 사용할 때, 때때로 우리는resultMap을 정의하지 않고 문장에 직접resultType을 지정할 수 있습니다.이때는 사실 Mybatis의 결과집이 자동으로 비치는 데 사용되었다.Mybatis의 자동 매핑은 기본적으로 열려 있습니다. 매핑할 때resultMap에 정의된 필드가 없는 필드를 이름과 같은 방식으로 되돌아오는 형식의 속성에 자동으로 매핑합니다.자동 매핑을 할 때 대소문자를 무시합니다. 예를 들어 검색 문장에서 검색된 필드는 ID입니다. 우리가 대응하는 반환 형식은 속성 id가 있고 setId() 방법이 있습니다. 그러면 id와 ID도 일치할 수 있고 자동으로 매핑할 수 있습니다. Mybatis는 검색된 결과에 필드 ID에 대응하는 값을 반환 형식 대상의 id 속성에 집중합니다.
1.1 소스 분석
자동 매핑에 대한 논리 규칙은 Mybatis의 Default Result SetHandler의 원본 코드를 참고할 수 있습니다. 핵심 코드는 다음과 같습니다. 

private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
  List<UnMappedColumAutoMapping> autoMapping = createAutomaticMappings(rsw, resultMap, metaObject, columnPrefix);
  boolean foundValues = false;
  if (autoMapping.size() > 0) {
   for (UnMappedColumAutoMapping mapping : autoMapping) {
    final Object value = mapping.typeHandler.getResult(rsw.getResultSet(), mapping.column);
    if (value != null || configuration.isCallSettersOnNulls()) {
     if (value != null || !mapping.primitive) {
      metaObject.setValue(mapping.property, value);
     }
     foundValues = true;
    }
   }
  }
  return foundValues;
 }
 private List<UnMappedColumAutoMapping> createAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
  final String mapKey = resultMap.getId() + ":" + columnPrefix;
  List<UnMappedColumAutoMapping> autoMapping = autoMappingsCache.get(mapKey);
  if (autoMapping == null) {
   autoMapping = new ArrayList<UnMappedColumAutoMapping>();
   final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
   for (String columnName : unmappedColumnNames) {
    String propertyName = columnName;
    if (columnPrefix != null && !columnPrefix.isEmpty()) {
     if (columnName.toUpperCase(Locale.ENGLISH).startsWith(columnPrefix)) {
      propertyName = columnName.substring(columnPrefix.length());
     } else {
      continue;
     }
    }
    final String property = metaObject.findProperty(propertyName, configuration.isMapUnderscoreToCamelCase());
    if (property != null && metaObject.hasSetter(property)) {
     final Class<?> propertyType = metaObject.getSetterType(property);
     if (typeHandlerRegistry.hasTypeHandler(propertyType)) {
      final TypeHandler<?> typeHandler = rsw.getTypeHandler(propertyType, columnName);
      autoMapping.add(new UnMappedColumAutoMapping(columnName, property, typeHandler, propertyType.isPrimitive()));
     }
    }
   }
   autoMappingsCache.put(mapKey, autoMapping);
  }
  return autoMapping;
 } 
위의 원본 코드에서createAutomaticMappings () 방법의 다음 문장은 현재 검색 결과가resultMap에 비치지 않은 필드를 가져와 자동으로 비추는 것입니다.자세한 내용은 완전한 원본 코드를 참고하십시오.

 final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
1.2 예
id,name,username,email,mobile 속성이 있는 사용자 클래스가 있다고 가정하고 다음의 검색과 그에 대응하는resultMap 정의가 있습니다.우리는 우리가 조회한 id,name,user_를 볼 수 있다name,email,mobile 필드,resultMap에서 필드만 설정했습니다user_name에 대응하는 것은username 속성입니다. 다른 것은 설정되지 않았습니다. 그러나 검색된 결과에서 사용자 대상의 id,name,username,email,mobile 속성은 모두 값이 있습니다. 왜냐하면 Mybatis에 의해 자동 맵 정책으로 값이 부여되기 때문입니다.

 <resultMap type="com.elim.learn.mybatis.model.User" id="BaseResult">
   <result column="user_name" property="username"/>
  </resultMap>
  <select id="findById" resultMap="BaseResult" parameterType="java.lang.Long" >
   select id,name,username user_name,email,mobile from t_user where id=#{id}
  </select>
1.3 자동 매핑 정책
Mybatis의 자동 매핑 정책은 기본적으로 열려 있으며, 기본적으로 끼워 넣지 않은resultMap에만 자동으로 매핑됩니다.이것은 Mybatis의 전역 설정인 autoMappingBehavior 매개 변수를 통해 설정된 것입니다.여기에는 NONE, PARTIAL, FULL 등 세 가지 수치가 있습니다.
l NONE 는 자동 매핑이 활성화되지 않음을 나타냅니다.
l PARTIAL은 중첩되지 않은resultMap에만 자동으로 매핑됨을 나타냅니다.
l FULL은 모든 resultMap을 자동으로 매핑합니다.

    <!--  , NONE、PARTIAL FULL, AutoMappingBehavior  -->
   <setting name="autoMappingBehavior" value="PARTIAL"/>
전역적으로 자동 맵을 사용할지 여부를 설정하는 것 외에 특정한resultMap에서 자동 맵을 사용할지 여부를 설정할 수 있습니다.이것은resultMap의 autoMapping 속성을 통해 설정된 것입니다. 선택할 수 있는 값은true와false입니다.resultMap에 정의된 autoMapping의 우선순위는 전역 설정의 우선순위보다 높습니다.
1.4 resultType 자동 매핑 분석
검색 문장의 반환 결과를 지정할 때 Result Type을 직접 지정할 수도 있고, Result Map을 지정할 수도 있으며, 지정한 Result Map의 type 속성으로 실제 반환 형식을 지정할 수도 있습니다.실제로 Mybatis의 밑바닥은 결과집을 처리할 때resultMap을 통해 처리된다.우리가 Result Type을 지정할 때, Mybatis 내부에 빈 Result Map을 생성하고, 그에 대응하는 type을 지정합니다.그러면 이 때 결과를 되돌려주면result Type 형식의 대응 속성에 자동으로 비추는 것이 위에서 소개한 Mybatis의 자동 비추는 메커니즘의 역할입니다.만약 이런 상황에서 우리가 전체 국면의 자동 매핑을 닫았다면, Mybatis는 자동으로 매핑할 수 없고, 우리가 필요로 하는 반환 결과를 얻지 못할 것이다.다음은 바로 지정한resultType입니다.

  <select id="findById" resultType="com.elim.learn.mybatis.model.User" parameterType="java.lang.Long" >
   select id,name,username,email,mobile from t_user where id=#{id}
  </select>
마이바티스의 마퍼.xml 파일의 내용은 XML Mapper Builder에 의해 해석되고, 그 중에서 정의된 Mapper 문장(select, insert 등)은 XML Statement Builder에 의해 해석되며, 해석된 후에 Mapped Statement가 생성됩니다.Select 문장에 대응하는resultMap의 해석의 핵심 논리는 다음과 같습니다. 더 많은 정보는 공식 원본 코드를 참고하십시오.

private List<ResultMap> getStatementResultMaps(
   String resultMap,
   Class<?> resultType,
   String statementId) {
  resultMap = applyCurrentNamespace(resultMap, true);
  List<ResultMap> resultMaps = new ArrayList<ResultMap>();
  if (resultMap != null) {
   String[] resultMapNames = resultMap.split(",");
   for (String resultMapName : resultMapNames) {
    try {
     resultMaps.add(configuration.getResultMap(resultMapName.trim()));
    } catch (IllegalArgumentException e) {
     throw new IncompleteElementException("Could not find result map " + resultMapName, e);
    }
   }
  } else if (resultType != null) {
   ResultMap inlineResultMap = new ResultMap.Builder(
     configuration,
     statementId + "-Inline",
     resultType,
     new ArrayList<ResultMapping>(),
     null).build();
   resultMaps.add(inlineResultMap);
  }
  return resultMaps;
 }
위에서 말한 것은 여러분께 소개해 드린 Mybatis 결과집이 자동으로 비치는 실례 코드입니다. 여러분께 도움이 되었으면 합니다. 만약에 궁금한 것이 있으면 저에게 메시지를 남겨 주십시오. 편집자는 제때에 여러분에게 회답할 것입니다.여기에서도 저희 사이트에 대한 지지에 감사드립니다!

좋은 웹페이지 즐겨찾기