mybatis对mapper.xml的解析(二)
对select,insert,update,delete的解析是通过buildStatementFromContext来完成的,具体的解析是XMLStatementBuilder来完成的.
支持的属性有
名称 | 说明 |
id | 语句id |
databaseId |
不处理语句情况 1、在配置文件中设置了databaseIdProvider,并且当前设置的databaseId与配置文件中不一致时 2、配置文件 中没有设置,当前设置了databaseId 3、配置文件中没有设置databaseIdProvider,当前没有设置databaseId,有当前id对应的MappedStatement的databaseId不等于null |
flushCache | 布尔值,如果没有设置情况下,如果是select语句,则默认为false,否则为true |
useCache | 布尔值,如果没有设置情况上,select语句默认是true,否则为false |
resultOrdered | 布尔值,没有设置时,默认是false |
parameterType | 设置语句请求参数类型,可以使用别名 |
lang | 设置语言驱动器,默认是XMLLanguageDriver |
selectKey | 生成主键节点 |
useGeneratedKey | 如果没有设置,使用全局配置及当前语句是不是插入语句 。如果为true,则使用Jdbc3KeyGenerator,否则使用NoKeyGenerator |
statementType | 没有设置时默认是PREPARE类型 |
fetchSize | 在StatementHandler中使用,来设置获取大小。 |
timeout | 在StatementHandler中设置语句的执行超时时间 |
parameterMap | 参数映射,已经不推荐使用 |
resultType | 一种特殊的resultMap |
resultMap | 与resultType相当,两者二选一 |
resultSetType | 用于在StatementHandler中设置语句的ResultType的类型 |
keyProperty | 用于设置主属性,有多个属性时,用逗号分隔。用于KeyGenerator |
keyColumn | 用于设置数据库字段主键,有多个时,用逗号分隔。用于KeyGenerator以及用于StatementHandler初始化语句时 |
resultSets | 有多个时,用逗号分隔。用于ResultSetHandler处理 |
selectKey支持的属性
名称 | 说明 |
databaseId |
不处理语句情况 1、在配置文件中设置了databaseIdProvider,并且当前设置的databaseId与配置文件中不一致时 2、配置文件 中没有设置,当前设置了databaseId 3、配置文件中没有设置databaseIdProvider,当前没有设置databaseId,有当前id对应的MappedStatement的databaseId不等于null |
resultType | 返回的数据类型 |
statementType | 如果没有设置,默认是PREPARE类型 |
keyProperty | 主属性 |
keyColumn | 数据库主键 |
order | 在什么时候执行,没有设置时,默认是AFTER |
1、解析语句中的include
XMLIncludeTransformer在解析include节点时,首先找到refid引用的节点,同时解析子节点property的name,value值对。接着在refid的引用的节点上应用applyIncludes递归调用。递归完后,用引用节点替换indlude节点。将引用节点的子结点添加到include之前,然后删除include节点。
在解析非include节点且节点类型是ELEMENT_NODE时,递归遍历子节点
如果解析的是引用节点,且节点是文本结点会作变量替换。
private void applyIncludes(Node source, final Properties variablesContext, boolean included) {if (source.getNodeName().equals("include")) {Node toInclude = findSqlFragment(getStringAttribute(source, "refid"), variablesContext);Properties toIncludeContext = getVariablesContext(source, variablesContext);applyIncludes(toInclude, toIncludeContext, true);if (toInclude.getOwnerDocument() != source.getOwnerDocument()) {toInclude = source.getOwnerDocument().importNode(toInclude, true);}source.getParentNode().replaceChild(toInclude, source);while (toInclude.hasChildNodes()) {toInclude.getParentNode().insertBefore(toInclude.getFirstChild(), toInclude);}toInclude.getParentNode().removeChild(toInclude);} else if (source.getNodeType() == Node.ELEMENT_NODE) {NodeList children = source.getChildNodes();for (int i = 0; i < children.getLength(); i++) {applyIncludes(children.item(i), variablesContext, included);}} else if (included && source.getNodeType() == Node.TEXT_NODE&& !variablesContext.isEmpty()) {// replace variables ins all text nodessource.setNodeValue(PropertyParser.parse(source.getNodeValue(), variablesContext));}}
2、解析selectKey节点
此结点在insert节点下,解析后添加到configuration中的keyGenerators中,添加后,删除selectKey节点
private void processSelectKeyNodes(String id, Class<?> parameterTypeClass, LanguageDriver langDriver) {List<XNode> selectKeyNodes = context.evalNodes("selectKey");if (configuration.getDatabaseId() != null) {parseSelectKeyNodes(id, selectKeyNodes, parameterTypeClass, langDriver, configuration.getDatabaseId());}parseSelectKeyNodes(id, selectKeyNodes, parameterTypeClass, langDriver, null);removeSelectKeyNodes(selectKeyNodes);}private void parseSelectKeyNodes(String parentId, List<XNode> list, Class<?> parameterTypeClass, LanguageDriver langDriver, String skRequiredDatabaseId) {for (XNode nodeToHandle : list) {String id = parentId + SelectKeyGenerator.SELECT_KEY_SUFFIX;String databaseId = nodeToHandle.getStringAttribute("databaseId");if (databaseIdMatchesCurrent(id, databaseId, skRequiredDatabaseId)) {parseSelectKeyNode(id, nodeToHandle, parameterTypeClass, langDriver, databaseId);}}}private void parseSelectKeyNode(String id, XNode nodeToHandle, Class<?> parameterTypeClass, LanguageDriver langDriver, String databaseId) {String resultType = nodeToHandle.getStringAttribute("resultType");Class<?> resultTypeClass = resolveClass(resultType);StatementType statementType = StatementType.valueOf(nodeToHandle.getStringAttribute("statementType", StatementType.PREPARED.toString()));String keyProperty = nodeToHandle.getStringAttribute("keyProperty");String keyColumn = nodeToHandle.getStringAttribute("keyColumn");boolean executeBefore = "BEFORE".equals(nodeToHandle.getStringAttribute("order", "AFTER"));//defaultsboolean useCache = false;boolean resultOrdered = false;KeyGenerator keyGenerator = NoKeyGenerator.INSTANCE;Integer fetchSize = null;Integer timeout = null;boolean flushCache = false;String parameterMap = null;String resultMap = null;ResultSetType resultSetTypeEnum = null;SqlSource sqlSource = langDriver.createSqlSource(configuration, nodeToHandle, parameterTypeClass);SqlCommandType sqlCommandType = SqlCommandType.SELECT;builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,resultSetTypeEnum, flushCache, useCache, resultOrdered,keyGenerator, keyProperty, keyColumn, databaseId, langDriver, null);id = builderAssistant.applyCurrentNamespace(id, false);MappedStatement keyStatement = configuration.getMappedStatement(id, false);configuration.addKeyGenerator(id, new SelectKeyGenerator(keyStatement, executeBefore));}private void removeSelectKeyNodes(List<XNode> selectKeyNodes) {for (XNode nodeToHandle : selectKeyNodes) {nodeToHandle.getParent().getNode().removeChild(nodeToHandle.getNode());}}
3、根据参数类型创建SqlSource
包含解析动态节点,创建DynamicSqlSource或者RawSqlSource
SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);
4、创建MappedStatement,添加到Configuration中
//XMLStatementBuilder
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,resultSetTypeEnum, flushCache, useCache, resultOrdered,keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);//MappedBuilderAssistant
public MappedStatement addMappedStatement(String id,SqlSource sqlSource,StatementType statementType,SqlCommandType sqlCommandType,Integer fetchSize,Integer timeout,String parameterMap,Class<?> parameterType,String resultMap,Class<?> resultType,ResultSetType resultSetType,boolean flushCache,boolean useCache,boolean resultOrdered,KeyGenerator keyGenerator,String keyProperty,String keyColumn,String databaseId,LanguageDriver lang,String resultSets) {if (unresolvedCacheRef) {throw new IncompleteElementException("Cache-ref not yet resolved");}id = applyCurrentNamespace(id, false);boolean isSelect = sqlCommandType == SqlCommandType.SELECT;MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType).resource(resource).fetchSize(fetchSize).timeout(timeout).statementType(statementType).keyGenerator(keyGenerator).keyProperty(keyProperty).keyColumn(keyColumn).databaseId(databaseId).lang(lang).resultOrdered(resultOrdered).resultSets(resultSets).resultMaps(getStatementResultMaps(resultMap, resultType, id)).resultSetType(resultSetType).flushCacheRequired(valueOrDefault(flushCache, !isSelect)).useCache(valueOrDefault(useCache, isSelect)).cache(currentCache);ParameterMap statementParameterMap = getStatementParameterMap(parameterMap, parameterType, id);if (statementParameterMap != null) {statementBuilder.parameterMap(statementParameterMap);}MappedStatement statement = statementBuilder.build();configuration.addMappedStatement(statement);return statement;}
mybatis对mapper.xml的解析(二)相关推荐
- mybatis对mapper.xml的解析(一)
对于mapper配置文件的解析是通过XMLMapperBuilder来完成的,其主要是解析结点为mapper下的结点 public void parse() {if (!configuration.i ...
- mybatis对mapper.xml的解析(三)
mybatis中对语句的解析使用了组合模式,针对不同的sql结点处理抽象出了SqlNode.详细的设计图为 什么时候创建不同的SqlSource? 创建DynamicSqlSource情况: 在包含有 ...
- Mybatis实现*mapper.xml热部署-分子级更新
需求: 项目在开发阶段或是修复bug阶段,会有修改mybatis的mapper.xml的时候,修改一般情况都要重启才能生失效,如果是分布式项目重启有时会耗时很久,都是无尽的等待.如果频繁修改,那么时间 ...
- idea中 mybatis 的 mapper.xml 新建没有 头文件
idea中 mybatis 的 mapper.xml 新建没有 头文件 解决步骤: 1.直接 settings 2.直接 选择 MybatisMapper 添加: <?xml version=& ...
- 扫描mybatis的mapper.xml
扫描mybatis的mapper.xml 扫描mybatis的mapper.xml 扫描mybatis的mapper.xml <!-- 如果不添加此节点mybatis的mapper.xml文件都 ...
- sql server解析xml属性为表格_[Mybatis][基础支持层]mapper xml sql 解析
该系列文章针对 Mybatis 3.5.1 版本 Mybatis 中 标签解析,主要是为了得到两大部分数据 1.Mapper.class 接口 2.SQL 执行语句,结果集映射关系等数据 在上一章中提 ...
- MyBatis中的Mapper.xml文件解析
具体可以参见MyBatis中文开发文档:https://mybatis.org/mybatis-3/zh/sqlmap-xml.html 我所述的主要有常用的几个标签和属性 一.parameterTy ...
- mybatis的mapper.xml文件中含有中文注释时运行出错,mybatis配置优化和别名优化 mybatis配置之映射器说明
记录一个发现的小问题,刚刚在UserMapper.xml文件中有一段中文注释掉的内容: <!-- <resultMap id="Usermap" type=" ...
- Mybatis学习--Mapper.xml映射文件
简介 Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心. 映射文件中有很多属性,常用的就是parameterType(输入类型 ...
最新文章
- synchronized底层原理_你用过synchronized吗?它的底层原理是什么?Java经典面试题来了...
- php中处理xml文件的类 simpleXML
- 使用FragmentTabHost和ViewPager实现仿微信主界面侧滑
- layui table 分页 记住之前勾选的数据
- 一文看尽10篇目标检测最新论文(SpineNet/AugFPN/LRF-Net/SABL/DSFPN等)
- css3 box-shadow阴影(内外阴影与发光)讲解
- 计算机二级考试试题在线看,【TOP182015年全国计算机二级考试试题题库.doc文档免费在线阅读材料】...
- 大型网站架构系列:负载均衡详解(4)
- Shell多线程编程的实例
- 寒江独钓——win内核编程读书笔记-1
- hdu5258简单枚举
- IPsec简单实验-IKE协商
- 20190301 小中大
- C语言书籍阅读-读书笔记--《C专家编程》
- 什么是RS232电平?什么是TTL电平?
- 如何让函数只执行一次
- python虚拟串口_python 虚拟串口通信
- 微信朋友圈点赞测试用例
- 008 怎么取消隐藏文件扩展名
- Oracle10g卡顿,192MB内存运行win10 系统启动大约3分钟响应非常慢
热门文章
- LeetCode59 Spiral Matrix II
- ExtJS实现完美Grid(2)--分组统计
- RS-232串行口连接线 com口连接线 并口链接线 双绞线 交叉线 直连线
- 百度 php 图片文字识别,PHP实现百度OCR文字识别
- java list用法_java list的用法详解
- python怎么导入包-python模块之导入包及模块发布
- python是什么编程教程-python教程看完了,还是不会编程?
- python怎么导入视频-Python模块导入详解
- python27-python27安装
- python好学吗mooc中文网-Python的N种玩法_中国大学MOOC(慕课)