Analysis of the principle of Mybatis data encapsulation process

Mybatis encapsulates the data process: The decorative design pattern is widely used in mybatis.
1. The simplest case: resultMap is not configured in xml, that is, the query is directly encapsulated into javabean.
mybatis source code:
DefaultResultSetHandler.class
//Query all columns written in sql from the wrapper class ResultSetWrapper of resultSet.
final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
    boolean foundValues = false;
    for (String columnName : unmappedColumnNames) {
      String propertyName = columnName;
      if (columnPrefix != null && columnPrefix.length() > 0) {
        // When columnPrefix is specified,
        // ignore columns without the prefix.
        if (columnName.toUpperCase(Locale.ENGLISH).startsWith(columnPrefix)) {
          propertyName = columnName.substring(columnPrefix.length());
        } else {
          continue;
        }
      }
      //Query whether there is the property in the Object from the metaObject. metaObject is the wrapper class of ObjectWrapper.ObjectWrapper is the wrapper class of Object
      final String property = metaObject.findProperty(propertyName, configuration.isMapUnderscoreToCamelCase());
      if (property != null && metaObject.hasSetter(property)) {
	//get the field type
        final Class<?> propertyType = metaObject.getSetterType(property);
        if (typeHandlerRegistry.hasTypeHandler(propertyType)) {
	  //Get the typeHandler that handles the field type	
          final TypeHandler<?> typeHandler = rsw.getTypeHandler(propertyType, columnName);
	  //get value
          final Object value = typeHandler.getResult(rsw.getResultSet(), columnName);
          if (value != null || configuration.isCallSettersOnNulls()) { // issue #377, call setter on nulls
            if (value != null || !propertyType.isPrimitive()) {
	    //Settings
              metaObject.setValue(property, value);
            }
            foundValues = true;
          }
        }
      }
    }

2. The principle of encapsulating one-to-many relationship or one-to-one relationship of collection:
    First, when the project is loaded, read the <resultMap> tag in xml and encapsulate it into ResultMap, where each result in ResultMap corresponds to ResultMapping.
public class ResultMap {
  private String id;
  private Class<?> type;
  private List<ResultMapping> resultMappings;
  private List<ResultMapping> idResultMappings;
  private List<ResultMapping> constructorResultMappings;
  private List<ResultMapping> propertyResultMappings;
  private Set<String> mappedColumns;
  private Discriminator discriminator;
  private boolean hasNestedResultMaps; //Whether there are nested tags
  private boolean hasNestedQueries;
  private Boolean autoMapping;
resultMap corresponds to the <resultMap> tag


public class ResultMapping {

  private Configuration configuration;
  private String property;
  private String column;
  private Class<?> javaType;
  private JdbcType jdbcType;
  private TypeHandler<?> typeHandler;
  private String nestedResultMapId;
  private String nestedQueryId;
  private Set<String> notNullColumns;
  private String columnPrefix;
  private List<ResultFlag> flags;
  private List<ResultMapping> composites;
  private String resultSet;
  private String foreignColumn;
  private boolean lazy;
ResultMapping corresponds to the <result tag><collection tag, etc.> under the <ResultMap> tag

public class DefaultResultSetHandler implements ResultSetHandler This class is a class that handles result set mapping, which defines two Maps:
private final Map<CacheKey, Object> nestedResultObjects = new HashMap<CacheKey, Object>(); When saving the entity class object in the one-to-many relationship mapping, first take the object from the Map, if there is one, take it out, if not, take it out New. CacheKey is generated based on the primary key.

  private final Map<CacheKey, Object> ancestorObjects = new HashMap<CacheKey, Object>(); Save the object of the entity nested class, first judge whether there is an object in the Map according to the CacheKey, if there is, take it out, if not, create a new one. CacheKey is generated based on the id of the nested class. This is why the id tag must be configured when configuring the collection, because when encapsulating a one-to-many relationship, it is based on the id to determine whether there is the same object and then encapsulate it.
 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326710816&siteId=291194637