Mybatis3源码分析(03)-加载Configuration-ResultMap说明
来源:互联网 发布:sql数据库教学视频 编辑:程序博客网 时间:2024/05/17 02:09
XMLMapperBuilder简单说明
XMLMapperBuildery主要是加载mapper配置文件加Configuration中。主要加载两大内容
- ResultMap:结果集映射,对应Configuration中的resultMaps属性
protected final Map<String, ResultMap> resultMaps = new StrictMap<ResultMap>("Result Maps collection");
- sql:即mapper配置文件中的select、update、insert、delete节点。对应Configuration中的mappedStatements
protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>("Mapped Statements collection");
Configuration内部类StrictMap分析
StrictMap继承了HashMap<String,T>主要增加了如下三点:
- 多了一个名字,然而并没有什么用处
public StrictMap(String name) { super(); this.name = name; }
- 重写了put方法
public V put(String key, V value) { if (containsKey(key)) //如果已经存在key,抛出异常 throw new IllegalArgumentException(name + " already contains value for " + key); if (key.contains(".")) {//key中是否存在"." //getShortName()方法获取了最后一个"."之后的字符,如:key=com.ashan.Hello,那么shortName=Hello final String shortKey = getShortName(key); //再判断shortKey是否已经存在了 if (super.get(shortKey) == null) { //如果不存在,直接设置 super.put(shortKey, value); } else { //如果已经存在,设置为一个特殊的对象,标识shortName同时对应的了多个值 super.put(shortKey, (V) new Ambiguity(shortKey)); } } return super.put(key, value); }
这个put方法主要逻辑:- 如果key已经存在,将直接报错
- 如果key还未存在,直接设置
- 如果key中包含了"."符号,截取最后一个"."符号后面的字符串做为shortName
- 如果shortName之前已经存在,将shortName对应的值设置为一个特殊对名,get方法如果获取一个特殊对象里将报错
- 如果shortName未存在,将shortName对应的值设置成与key对应的值一样
put(com.ashan.selectUserById,"select * from tab_user where id=?")
map里将这样保存数据(两key对应同一个value)com.ashan.selectUserById="select * from tab_user where id=?" selectUserById="select * from tab_user where id=?"
- 重写了get方法
public V get(Object key) { V value = super.get(key); if (value == null) { throw new IllegalArgumentException(name + " does not contain value for " + key); } if (value instanceof Ambiguity) {//如果为特殊对象Ambiguity,同一个shortName有多个命名空间使用,所有不允许用shortName方法,必须加上命名空间访问 throw new IllegalArgumentException(((Ambiguity) value).getSubject() + " is ambiguous in " + name + " (try using the full name including the namespace, or rename one of the entries)"); } return value; }
StrictMap只是增加了对命名空间的支持,并没有太多的逻辑!
ResultMap类
mapper配置文件中的resultMap节点最终会被解析成一个ResultMap对象,这个对象中包含多个ResultMapping对象,我们可以这样子认为,ResultMap为一个java对象和一个结果集/表中的一行记录对应,ResultMapping为一个java对象中的属性和一个结果集/表某一行的某一个字段对应。如下示例:
<resultMap type="com.ashan.mybatis.User" id="detailUserResultMap"><!-- 整个resultMap会被解析成一个ResultMap对应 --><constructor><idArg column="user_id" javaType="String"/><!-- idArg会被解析成一个resultMapping对象 --><arg column="user_name"/><!-- resultMapping对象 --></constructor><result property="password" column="user_pwd" /><!-- resultMapping对象 --><result property="type" column="user_type" javaType="com.ashan.mybatis.UserType" <!-- resultMapping对象 --> typeHandler="com.ashan.mybatis.UserTypeHandler"/><result property="svcnum" column="svc_num" /> <!-- resultMapping对象 --><association property="cust" javaType="com.ashan.mybatis.Cust"> <!-- resultMapping对象 这个resultMapping对象指向了另一个ResultMap--><id property="id" column="cust_id"/><result property="custname" column="cust_name"/><result property="certNo" column="cert_no"/></association><collection property="accts" ofType="com.ashan.mybatis.Acct"><id property="id" column="acct_id" /><result property="payName" column="pay_name"/><result property="bankNo" column="bank_no"/></collection></resultMap>
ResultMap的主要属性
//id="detailUserResultMap" private String id; //type="com.ashan.mybatis.User" private Class<?> type; //所有的resultMapping对象,包括constructor/idArg,constructor/arg,result,association,collection,但不包括association和collection里的子节点 //上图中应该有7个 private List<ResultMapping> resultMappings; //包括constructor/idArg,id private List<ResultMapping> idResultMappings; //constructor里的子节点 private List<ResultMapping> constructorResultMappings; //除constructor里的子节点,其他都是,result,association,collection,id private List<ResultMapping> propertyResultMappings; //所有被映射的列 private Set<String> mappedColumns; //比较少用 private Discriminator discriminator; //是否有内映射,上图中association, collection都为内映射,内查询不算(就是的reulst节点中配置select属性的情况) private boolean hasNestedResultMaps; //是否有查询, private boolean hasNestedQueries; //是否要求自动映射 private Boolean autoMapping;ResultMap.Builder.build()方法
public ResultMap build() { if (resultMap.id == null) { throw new IllegalArgumentException("ResultMaps must have an id"); } resultMap.mappedColumns = new HashSet<String>(); resultMap.idResultMappings = new ArrayList<ResultMapping>(); resultMap.constructorResultMappings = new ArrayList<ResultMapping>(); resultMap.propertyResultMappings = new ArrayList<ResultMapping>(); //遍历所有的resultMapping for (ResultMapping resultMapping : resultMap.resultMappings) { //如果其中一个resultMapping有内查询,则这个resultMap也就是有内查询 resultMap.hasNestedQueries = resultMap.hasNestedQueries || resultMapping.getNestedQueryId() != null; //如果其中一个resultMapping有内映射,则这个resultMap也就是有内映射 resultMap.hasNestedResultMaps = resultMap.hasNestedResultMaps || (resultMapping.getNestedResultMapId() != null && resultMapping.getResultSet() == null); final String column = resultMapping.getColumn(); if (column != null) { resultMap.mappedColumns.add(column.toUpperCase(Locale.ENGLISH)); } else if (resultMapping.isCompositeResult()) { //组合的配置 for (ResultMapping compositeResultMapping : resultMapping.getComposites()) { final String compositeColumn = compositeResultMapping.getColumn(); if (compositeColumn != null) { resultMap.mappedColumns.add(compositeColumn.toUpperCase(Locale.ENGLISH)); } } } if (resultMapping.getFlags().contains(ResultFlag.CONSTRUCTOR)) { resultMap.constructorResultMappings.add(resultMapping); } else { resultMap.propertyResultMappings.add(resultMapping); } if (resultMapping.getFlags().contains(ResultFlag.ID)) { resultMap.idResultMappings.add(resultMapping); } } if (resultMap.idResultMappings.isEmpty()) { resultMap.idResultMappings.addAll(resultMap.resultMappings); } // lock down collections resultMap.resultMappings = Collections.unmodifiableList(resultMap.resultMappings); resultMap.idResultMappings = Collections.unmodifiableList(resultMap.idResultMappings); resultMap.constructorResultMappings = Collections.unmodifiableList(resultMap.constructorResultMappings); resultMap.propertyResultMappings = Collections.unmodifiableList(resultMap.propertyResultMappings); resultMap.mappedColumns = Collections.unmodifiableSet(resultMap.mappedColumns); return resultMap; }
ResultMapping主要属性
private Configuration configuration; //java对象的属性名 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; private String columnPrefix; private List<ResultFlag> flags; private List<ResultMapping> composites; private String resultSet; private String foreignColumn; private boolean lazy;这个类就是一个普通的java对象,本身没有什么逻辑,要想知道属性是怎么产生的,还得分析XMLMapperBuildery的源代码。
0 0
- Mybatis3源码分析(03)-加载Configuration-ResultMap说明
- Mybatis3源码分析(04)-加载Configuration-XMLMapperBuilder加载ResultMap
- Mybatis3源码分析(02)-加载Configuration-XMLConfigBuilder
- Mybatis3源码分析(07)-加载Configuration-总结
- Mybatis3源码分析(05)-加载Configuration-加载MappedStatement
- Mybatis3源码分析(06)-加载Configuration-缓存配置加载
- Mybatis3源码分析(08)-加载Configuration-使用到的设计模式
- Mybatis3源码分析(09)-SqlSession创建及简要说明
- Mybatis3源码分析(20)-Mapper实现-配置加载
- Mybatis3源码分析(22)-总结
- Mybatis3 resultMap 官方应用
- Mybatis3源码分析(11)-Sql解析执行-BoundSql的加载-1
- Mybatis3源码分析(13)-Sql解析执行-BoundSql的加载-2
- mybatis3--7.resultMap高级映射
- Mybatis3源码分析(四):总结
- Mybatis3源码分析(01)-前期准备
- Hadoop源码分析之Configuration
- Hadoop源码分析之Configuration
- 【Solutions系列】可视化和攻击范围分析模板
- Strongswan与Andriod野蛮模式L2TPoverIPsec对接有时候不成功。
- canvas 响应鼠标火焰喷射
- 数据库常用命令
- 上传下载分布式部署FASTDFS安装与配置
- Mybatis3源码分析(03)-加载Configuration-ResultMap说明
- js判断IE版本
- Android中的windowSoftInputMode属性详解
- sql查看alert日志
- hdu-1163 Eddy's digital Roots
- spring
- Java之——serialVersionUID的作用
- Spring中如何配置Hibernate事务
- iOS开发实现打电话、发邮件等外部应用的关联