25、Result解析之ResultMapping介绍

来源:互联网 发布:ubuntu 搭建视频服务器 编辑:程序博客网 时间:2024/06/05 19:48

ResultMapping

字段映射 一个ResultMapping实例对应ResultSet中一个字段到javaBean中一个属性的映射关系

字段

public class ResultMapping {    private Configuration configuration;    /**     * 字段名     */    private String property;    /**     * 数据库的列明     */    private String column;    /**     * 字段名的类型     */    private Class<?> javaType;    /**     * 列的类型     */    private JdbcType jdbcType;    /**     * 类型处理器     */    private TypeHandler<?> typeHandler;    /**     * 内部映射的ResultMapId     */    private String nestedResultMapId;    /**     * 内查询ID     */    private String nestedQueryId;    /**     * 不能为     */    private Set<String> notNullColumns;    /**     * 对应元素的columnPrefix属性     */    private String columnPrefix;    /**     * 处理后的标志,标志共两个:id和constructor     */    private List<ResultFlag> flags;    /**     * ResultMapping的位置     */    private List<ResultMapping> composites;    /**     * 对应元素的resultSet属性     */    private String resultSet;    /**     * 对应元素的foreignColumn属性     */    private String foreignColumn;    /**     * 是否延迟加载,对应元素的fetchType属性值,lazy则为true否则为false     */    private boolean lazy;    }

通用属性配置(每个属性映射元素都包含的属性)如下:
- property:结果对象中要映射到的目标属性的属性名称
- column:结果集中被映射的字段的名称
- javaType:结果对象中要映射到的目标属性的类型的Class对象
- jdbcType:结果集中被映射的字段的类型,只是用来与javaType一起确定类型处理器的

构造方法

 ResultMapping() {    }

此类没有set方法,只有get方法,而构造方法也是无参的

属性的赋值是通过内部类来赋值的。

此处使用的是典型的build设计模式

build

字段

  private ResultMapping resultMapping = new ResultMapping();

构造方法

       public Builder(Configuration configuration, String property, String column, TypeHandler<?> typeHandler) {            this(configuration, property);            resultMapping.column = column;            resultMapping.typeHandler = typeHandler;        }        public Builder(Configuration configuration, String property, String column, Class<?> javaType) {            this(configuration, property);            resultMapping.column = column;            resultMapping.javaType = javaType;        }        public Builder(Configuration configuration, String property) {            resultMapping.configuration = configuration;            resultMapping.property = property;            resultMapping.flags = new ArrayList<ResultFlag>();            resultMapping.composites = new ArrayList<ResultMapping>();            resultMapping.lazy = configuration.isLazyLoadingEnabled();        }

此处有3个构造方法构成重载,就是简单的对属性进行复制

build方法

 public ResultMapping build() {            // lock down collections            resultMapping.flags = Collections.unmodifiableList(resultMapping.flags);            resultMapping.composites = Collections.unmodifiableList(resultMapping.composites);            resolveTypeHandler();            validate();            return resultMapping;        }

此处使用了unmodifiableList,意味着得到的flags和composites属性是不能修改的
此处还调用了resolveTypeHandler方法和validate方法

resolveTypeHandler

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

通过从configuration对象中得到类型处理器的管理器,然后根据javaType和jdbcType从管理器中得到,对应的类型处理器

validate

 private void validate() {            // Issue #697: cannot define both nestedQueryId and nestedResultMapId            if (resultMapping.nestedQueryId != null && resultMapping.nestedResultMapId != null) {                throw new IllegalStateException("Cannot define both nestedQueryId and nestedResultMapId in property " + resultMapping.property);            }            // Issue #5: there should be no mappings without typehandler            if (resultMapping.nestedQueryId == null && resultMapping.nestedResultMapId == null && resultMapping.typeHandler == null) {                throw new IllegalStateException("No typehandler found for property " + resultMapping.property);            }            // Issue #4 and GH #39: column is optional only in nested resultmaps but not in the rest            if (resultMapping.nestedResultMapId == null && resultMapping.column == null && resultMapping.composites.isEmpty()) {                throw new IllegalStateException("Mapping is missing column attribute for property " + resultMapping.property);            }            if (resultMapping.getResultSet() != null) {                int numColumns = 0;                if (resultMapping.column != null) {                    numColumns = resultMapping.column.split(",").length;                }                int numForeignColumns = 0;                if (resultMapping.foreignColumn != null) {                    numForeignColumns = resultMapping.foreignColumn.split(",").length;                }                if (numColumns != numForeignColumns) {                    throw new IllegalStateException("There should be the same number of columns and foreignColumns in property " + resultMapping.property);                }            }        }

小结

对象属性值有3种来源(优先级从高到低)
1. 来自于一个新的select语句产生的新结果集(通过select属性引用另一个元素的id)
2. 来自于多余的结果集对象中,这种来源的前提是allowMultiQueries=true允许多sql查询。还需要给每个结果集设置一个名称。在属性映射中配置resultSet属性引用结果集名称(如:)
3. 来自于结果集中的若干个字段(根据resultMap映射关系)或某一个(根据column属性值)

在嵌套属性映射(两种元素)中,column属性默认无效(因为存在resultMap),只有当存在select属性时,column属性才有效。且select属性和resultMap属性不能同时存在。

原创粉丝点击