30、SQL片段的解析
来源:互联网 发布:网络微营销 编辑:程序博客网 时间:2024/06/05 23:04
sqlFragment
可以翻译为sql片段,它的存在价值在于可复用sql片段,避免到处重复编写。
sqlFragment的解析过程
sqlFragment存储于Configuration内部。
protected final Map<String, XNode> sqlFragments = new StrictMap<XNode>("XML fragments parsed from previous mappers");
解析sqlFragment的过程非常简单。
org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XNode)方法部分源码。
private void sqlElement(List<XNode> list, String requiredDatabaseId) throws Exception { for (XNode context : list) { String databaseId = context.getStringAttribute("databaseId"); String id = context.getStringAttribute("id"); id = builderAssistant.applyCurrentNamespace(id, false); if (databaseIdMatchesCurrent(id, databaseId, requiredDatabaseId)) { sqlFragments.put(id, context); } } }
解析include标签的过程
org.apache.ibatis.builder.xml.XMLStatementBuilder.parseStatementNode()方法源码。
//解析导入的SQL片段 XMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant); includeParser.applyIncludes(context.getNode());
org.apache.ibatis.builder.xml.XMLIncludeTransformer.applyIncludes(Node, Properties)方法源码。
private void applyIncludes(Node source, final Properties variablesContext, boolean included) { //节点的名字是否是include 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); } // 将include节点,替换为sqlFragment节点 source.getParentNode().replaceChild(toInclude, source); while (toInclude.hasChildNodes()) { // 将sqlFragment的子节点(也就是文本节点),插入到sqlFragment的前面 toInclude.getParentNode().insertBefore(toInclude.getFirstChild(), toInclude); } // 移除sqlFragment节点 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()) {//该节点是否是内容,并且配置文件中配置有property属性 // 通过PropertyParser替换所有${xxx}占位符(attribute属性) source.setNodeValue(PropertyParser.parse(source.getNodeValue(), variablesContext)); } }
图示过程演示
以下内容为,摘自其他博客
- 解析节点
<select id="countAll" resultType="int"> select count(1) from ( <include refid="studentProperties"></include> ) tmp</select>
- include节点替换为sqlFragment节点
<select id="countAll" resultType="int"> select count(1) from ( <sql id="studentProperties"> select stud_id as studId , name, email , dob , phone from students </sql> ) tmp</select>
- 将sqlFragment的子节点(文本节点)insert到sqlFragment节点的前面。注意,对于dom来说,文本也是一个节点,叫TextNode。
<select id="countAll" resultType="int"> select count(1) from ( select stud_id as studId , name, email , dob , phone from students <sql id="studentProperties"> select stud_id as studId , name, email , dob , phone from students </sql> ) tmp</select>
- 移除sqlFragment节点
<select id="countAll" resultType="int"> select count(1) from ( select stud_id as studId , name, email , dob , phone from students ) tmp</select>
小结
PropertyParser.parse(source.getNodeValue(), variablesContext);
会替换出现的#{XX},如果xx出现在property文件中,则替换相应的值
阅读全文
0 0
- 30、SQL片段的解析
- 使用SQL Server的OpenXML解析带有命名空间的XML片段
- sql片段
- Jsoup解析html某片段的问题
- 时间比较的SQL语句片段
- Sax解析代码片段
- xml解析片段
- XHTML中,js的CData片段出现的解析
- SQL 代码片段
- SQL注入片段
- JavaEE_Mybatis_SpringMVC_Mybatis_lesson9_引用SQL片段
- Sql查询片段
- 动态SQL片段
- 远程数据库导数据的存储过程片段(sql)
- MyBatis中sql片段的定义与引用
- 对Request.url片段解析
- configure配置脚本片段解析
- 30+有用的CSS代码片段
- 28、参数容器ParameterMapping介绍和解析
- centos的软件安装方法rpm和yum
- 使用Thread+Handler或runOnUiThread更新UI
- 贪心经典题目
- 29、ParamNameResolver参数解析
- 30、SQL片段的解析
- 377. Combination Sum IV
- SVN安装、MyEclipse安装SVN插件以及上传项目
- mysql安装及连接
- ES6规范大全
- 文章标题
- Angular2 父子路由问题
- 31、propertise解析之通用标记解析器与标记处理器
- uml关联符号说明