2019独角兽企业重金招聘Python工程师标准>>>

本章中分析insert元素的解析。

1 配置文件

<insert id="insert" parameterType="cn.vansky.schedule.time.menu.bo.Menu"><!--WARNING - @mbggeneratedThis element is automatically generated by MyBatis Generator, do not modify.This element was generated on Fri Aug 14 16:08:36 CST 2015.-->insert into tb_menu (menu_name, menu_remark, menu_parent_id, menu_url, is_show, is_delete, operation_user_name, operation_time)values (#{menuName,jdbcType=VARCHAR}, #{menuRemark,jdbcType=VARCHAR}, #{menuParentId,jdbcType=INTEGER}, #{menuUrl,jdbcType=VARCHAR}, #{isShow,jdbcType=TINYINT}, #{isDelete,jdbcType=TINYINT}, #{operationUserName,jdbcType=VARCHAR}, #{operationTime,jdbcType=TIMESTAMP})
</insert>

2 方法buildStatementFromContext

private void buildStatementFromContext(List<XNode> list) {if (configuration.getDatabaseId() != null) {buildStatementFromContext(list, configuration.getDatabaseId());}buildStatementFromContext(list, null);}private void buildStatementFromContext(List<XNode> list, String requiredDatabaseId) {for (XNode context : list) {// 对一个SQL进行解析final XMLStatementBuilder statementParser = new XMLStatementBuilder(configuration, builderAssistant, context, requiredDatabaseId);try {statementParser.parseStatementNode();} catch (IncompleteElementException e) {configuration.addIncompleteStatement(statementParser);}}
}

上面是一个总的方法包括,insert、update、delete、select4中元素都会进入此方法。这里也会捕获一种异常,并把错误的解析放入Configuration(全局配置类)的Collection<XMLStatementBuilder> incompleteStatements = new LinkedList<XMLStatementBuilder>()。

3 方法parseStatementNode

public void parseStatementNode() {// insertString id = context.getStringAttribute("id");// nullString databaseId = context.getStringAttribute("databaseId");// 第一次检查这里是不通过的,直接跳过if (!databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) return;// null Integer fetchSize = context.getIntAttribute("fetchSize");// nullInteger timeout = context.getIntAttribute("timeout");// nullString parameterMap = context.getStringAttribute("parameterMap");// cn.vansky.schedule.time.menu.bo.MenuString parameterType = context.getStringAttribute("parameterType");// class cn.vansky.schedule.time.menu.bo.MenuClass<?> parameterTypeClass = resolveClass(parameterType);// nullString resultMap = context.getStringAttribute("resultMap");// nullString resultType = context.getStringAttribute("resultType");// nullString lang = context.getStringAttribute("lang");// 获取默认的处理对象// org.apache.ibatis.scripting.xmltags.XMLLanguageDriverLanguageDriver langDriver = getLanguageDriver(lang);// nullClass<?> resultTypeClass = resolveClass(resultType);// nullString resultSetType = context.getStringAttribute("resultSetType");// PREPAREDStatementType statementType = StatementType.valueOf(context.getStringAttribute("statementType", StatementType.PREPARED.toString()));// nullResultSetType resultSetTypeEnum = resolveResultSetType(resultSetType);// insertString nodeName = context.getNode().getNodeName();// INSERTSqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));// falseboolean isSelect = sqlCommandType == SqlCommandType.SELECT;// trueboolean flushCache = context.getBooleanAttribute("flushCache", !isSelect);// falseboolean useCache = context.getBooleanAttribute("useCache", isSelect);// falseboolean resultOrdered = context.getBooleanAttribute("resultOrdered", false);// Include Fragments before parsingXMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant);// 解析<include refid="Base_Column_List" />includeParser.applyIncludes(context.getNode());// Parse selectKey after includes and remove them.processSelectKeyNodes(id, parameterTypeClass, langDriver);// 这里通过下面分析获取的SQL源(静态SQL源),因为没有动态标签SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);// nullString resultSets = context.getStringAttribute("resultSets");// nullString keyProperty = context.getStringAttribute("keyProperty");// nullString keyColumn = context.getStringAttribute("keyColumn");// org.apache.ibatis.executor.keygen.NoKeyGeneratorKeyGenerator keyGenerator;// insert!selectKeyString keyStatementId = id + SelectKeyGenerator.SELECT_KEY_SUFFIX;// cn.vansky.schedule.time.menu.dao.MenuMapper.insert!selectKeykeyStatementId = builderAssistant.applyCurrentNamespace(keyStatementId, true);if (configuration.hasKeyGenerator(keyStatementId)) {keyGenerator = configuration.getKeyGenerator(keyStatementId);} else {keyGenerator = context.getBooleanAttribute("useGeneratedKeys",configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType))? new Jdbc3KeyGenerator() : new NoKeyGenerator();}builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,resultSetTypeEnum, flushCache, useCache, resultOrdered, keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);}

方法XMLLanguageDriver.createSqlSource

public SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType) {XMLScriptBuilder builder = new XMLScriptBuilder(configuration, script, parameterType);// 入参Class及节点解析return builder.parseScriptNode();
}

5 方法XMLScriptBuilder.parseScriptNode

public SqlSource parseScriptNode() {// 解析动态标签,if、where、forList<SqlNode> contents = parseDynamicTags(context);// 所有动态标签集合类MixedSqlNode rootSqlNode = new MixedSqlNode(contents);SqlSource sqlSource = null;if (isDynamic) {sqlSource = new DynamicSqlSource(configuration, rootSqlNode);} else {sqlSource = new RawSqlSource(configuration, rootSqlNode, parameterType);}return sqlSource;
}

6 方法XMLScriptBuilder.parseDynamicTags

private List<SqlNode> parseDynamicTags(XNode node) {List<SqlNode> contents = new ArrayList<SqlNode>();// 获取动态标签与内容列表NodeList children = node.getNode().getChildNodes();for (int i = 0; i < children.getLength(); i++) {XNode child = node.newXNode(children.item(i));// 内容if (child.getNode().getNodeType() == Node.CDATA_SECTION_NODE || child.getNode().getNodeType() == Node.TEXT_NODE) {String data = child.getStringBody("");// 内容SqlNodeTextSqlNode textSqlNode = new TextSqlNode(data);// 动态修改的内容if (textSqlNode.isDynamic()) {contents.add(textSqlNode);isDynamic = true;} else {// 静态内容contents.add(new StaticTextSqlNode(data));}} else if (child.getNode().getNodeType() == Node.ELEMENT_NODE) { // issue #628// 节点为元素,也就是动态标签where、if、forString nodeName = child.getNode().getNodeName();// 获取动态标签处理器WhereHandler、ForEachHandlerNodeHandler handler = nodeHandlers.get(nodeName);if (handler == null) {throw new BuilderException("Unknown element <" + nodeName + "> in SQL statement.");}// 处理器处理内容,并把处理的内容加入到SQLNodehandler.handleNode(child, contents);isDynamic = true;}}return contents;}

方法5中有2中数据源DynamicSqlSource(动态SQL源)和RawSqlSource(静态SQL源),动态SQL源就是包括where、if、for,静态SQL源就是只包括SQL语句,下面就简单分析一下2中SQL源。

RawSqlSource(静态SQL源)

public RawSqlSource(Configuration configuration, String sql, Class<?> parameterType) {SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);Class<?> clazz = parameterType == null ? Object.class : parameterType;sqlSource = sqlSourceParser.parse(sql, clazz, new HashMap<String, Object>());
}
public SqlSource parse(String originalSql, Class<?> parameterType, Map<String, Object> additionalParameters) {// 参数处理MappingParameterMappingTokenHandler handler = new ParameterMappingTokenHandler(configuration, parameterType, additionalParameters);GenericTokenParser parser = new GenericTokenParser("#{", "}", handler);// 解析XML中的SQL语句,#{menuName,jdbcType=VARCHAR},转换成?及对应的处理类型ParameterMappingString sql = parser.parse(originalSql);return new StaticSqlSource(configuration, sql, handler.getParameterMappings());
}

这里直接解析并生成StaticSqlSource,包括SQL语句及对应的处理类型。

7.1 ParameterMapping对应的menuName

/** 全局配置类 */
private Configuration configuration;
/** menuName */
private String property;
/** IN:输入 */
private ParameterMode mode;
/** class java.lang.String */
private Class<?> javaType = Object.class;
/** VARCHAR */
private JdbcType jdbcType;
/** null */
private Integer numericScale;
/** StringTypeHandler */
private TypeHandler<?> typeHandler;
/** null */
private String resultMapId;
/** null */
private String jdbcTypeName;
/** null */
private String expression;

DynamicSqlSource(动态SQL源)

public DynamicSqlSource(Configuration configuration, SqlNode rootSqlNode) {this.configuration = configuration;this.rootSqlNode = rootSqlNode;
}

很明显这里没有进行生成SQL,那就是在具体获取SQL时进行生成SQL

9 方法addMappedStatement

此方法只是赋值,没有什么特殊处理,所以此方法不在分析,可以自行研究。

总结 

附上图片MappedStatement属性值

下面给出动态SQL源的MappedStatement属性值

<insert id="insertSelective" parameterType="cn.vansky.schedule.time.menu.bo.Menu"><!--WARNING - @mbggeneratedThis element is automatically generated by MyBatis Generator, do not modify.This element was generated on Fri Aug 14 16:08:36 CST 2015.-->insert into tb_menu<trim prefix="(" suffix=")" suffixOverrides=","><if test="menuName != null">menu_name,</if><if test="menuRemark != null">menu_remark,</if><if test="menuParentId != null">menu_parent_id,</if><if test="menuUrl != null">menu_url,</if><if test="isShow != null">is_show,</if><if test="isDelete != null">is_delete,</if><if test="operationUserName != null">operation_user_name,</if><if test="operationTime != null">operation_time,</if></trim><trim prefix="values (" suffix=")" suffixOverrides=","><if test="menuName != null">#{menuName,jdbcType=VARCHAR},</if><if test="menuRemark != null">#{menuRemark,jdbcType=VARCHAR},</if><if test="menuParentId != null">#{menuParentId,jdbcType=INTEGER},</if><if test="menuUrl != null">#{menuUrl,jdbcType=VARCHAR},</if><if test="isShow != null">#{isShow,jdbcType=TINYINT},</if><if test="isDelete != null">#{isDelete,jdbcType=TINYINT},</if><if test="operationUserName != null">#{operationUserName,jdbcType=VARCHAR},</if><if test="operationTime != null">#{operationTime,jdbcType=TIMESTAMP},</if></trim>
</insert>

其实这里属性都差不多,主要是SqlSource不一样,那么下来就看它的属性。

转载于:https://my.oschina.net/u/1269959/blog/523651

MyBatis整合Spring的实现(13)相关推荐

  1. MyBatis整合Spring的实现(2)

    2019独角兽企业重金招聘Python工程师标准>>> 分析 MyBatis整合Spring的实现(1)中代码实现的4.1可以知道,XMLConfigBuilder类读取MyBati ...

  2. MyBatis整合Spring原理分析

    目录 MyBatis整合Spring原理分析 MapperScan的秘密 简单总结 假如不结合Spring框架,我们使用MyBatis时的一个典型使用方式如下: public class UserDa ...

  3. (转)MyBatis框架的学习(六)——MyBatis整合Spring

    http://blog.csdn.net/yerenyuan_pku/article/details/71904315 本文将手把手教你如何使用MyBatis整合Spring,这儿,我本人使用的MyB ...

  4. Mybatis——Mybatis整合Spring详解

    mybatis-spring官网 1. MyBatis整合Spring实现 我们首先实现MyBatis和Spring的整合操作. 1.1 添加相关的依赖 这些是整合的依赖,不包括其他分页插件等依赖. ...

  5. 【Mybatis+spring整合源码探秘】--- mybatis整合spring事务原理

    文章目录 1 mybatis整合spring事务原理 1 mybatis整合spring事务原理 本篇文章不再对源码进行具体的解读了,仅仅做了下面一张图: 该图整理了spring+mybatis整合后 ...

  6. Spring学习笔记:Spring整合Mybatis(mybatis-spring.jar)(二:mybatis整合spring)

    http://blog.csdn.net/qq598535550/article/details/51703190 二.Spring整合mybatis其实是在mybatis的基础上实现Spring框架 ...

  7. MyBatis(五)MyBatis整合Spring原理分析

    前面梳理了下MyBatis在单独使用时的工作流程和关键源码,现在看看MyBatis在和Spring整合的时候是怎么工作的 也先从使用开始 Spring整合MyBatis 1.引入依赖,除了MyBati ...

  8. Mybatis整合spring

    整合思路 1.SqlSessionFactory对象应该放到spring容器中作为单例存在. 2.传统dao的开发方式中,应该从spring容器中获得sqlsession对象. 3.Mapper代理形 ...

  9. mybatis 整合spring之mapperLocations配置的问题

    今天尝试spring整合mybatis时遇到这么一个问题,就是在配置sqlSessionFactory时是否要配置mapperLocations的问题. <bean id="sessi ...

最新文章

  1. IE下a标签会触发window.onbeforeunload的问题
  2. java中的与或非_与或非 · java development · 看云
  3. 剑指offer(21)从上往下打印二叉树
  4. 大数据城市规划 杨东_AI为智慧城市规划做建设
  5. php图片上传报非法错误,老师,我在上传图片时,提示非法上传文件
  6. visual studio 2008 intellisense does not work
  7. Tatala 中文教程
  8. 一阶低通滤波器方程_一阶RC低通滤波器和RC高通滤波器简介-模拟/电源-与非网...
  9. java 浏览器设置字体大小_css 字体设置(不同浏览器设置效果)
  10. smoothstep(),平滑阶梯函数,平滑过渡函数
  11. 解决 git reject
  12. i7台式电脑配置推荐_高配游戏电脑 intel酷睿i7-8700配RTX2070六核台式电脑配置清单表...
  13. 实例分割: 一文读懂 E2EC (CVPR 2022)
  14. Cassandra Vs Voldemort
  15. border-radius详解分享
  16. hadoop错误org.apache.hadoop.yarn.exceptions.YarnException Unauthorized request to start container
  17. 数据分析 之 渠道质量分析
  18. php文章cms插件,Phpcms v9百度神马后台勾选文章推送插件
  19. 王者荣耀是用什么软件和编程语言开发的
  20. JAVA Web实现注册登录系统

热门文章

  1. 配置文件存int类型_Redis详解(五)------ redis的五大数据类型实现原理
  2. 在C语言中023是八进制数,C语言总结
  3. python getattr函数_Python中的getattr()函数详解
  4. docker配置 nacos_Nacos - 阿里开源配置中心
  5. 计算机机器人方向,计算机考研想学习智能机器人方向都有那几个学校呢..._考研_帮考网...
  6. 合并相同数据的行_R语言笔记(六):数据框重塑(reshape2)
  7. 【Java中级篇】使用itextpdf生成PDF
  8. apache log4j入门
  9. MySQL 数据库图形化管理界面应用种草之 Navicat Premium 如何使用
  10. C语言(CED)编写程序,求sum=1*1*1+2*2*2+3*3*3+4*4*4+5*5*5+····+n*n*n