一. insert

首先看一下 insert.java 的代码:

/**
* <p>
* 根据 ID 删除
* </p>
*
* @author hubin
* @since 2018-04-06
*/
public class Insert extends AbstractMethod { @Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
KeyGenerator keyGenerator = new NoKeyGenerator();
SqlMethod sqlMethod = SqlMethod.INSERT_ONE;
String columnScript = SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlColumn(),
StringPool.LEFT_BRACKET, StringPool.RIGHT_BRACKET, null, StringPool.COMMA);
String valuesScript = SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlProperty(),
StringPool.LEFT_BRACKET, StringPool.RIGHT_BRACKET, null, StringPool.COMMA);
String keyProperty = null;
String keyColumn = null;
// 表包含主键处理逻辑,如果不包含主键当普通字段处理
if (StringUtils.isNotEmpty(tableInfo.getKeyProperty())) {
if (tableInfo.getIdType() == IdType.AUTO) {
/** 自增主键 */
keyGenerator = new Jdbc3KeyGenerator();
keyProperty = tableInfo.getKeyProperty();
keyColumn = tableInfo.getKeyColumn();
} else {
if (null != tableInfo.getKeySequence()) {
keyGenerator = TableInfoHelper.genKeyGenerator(tableInfo, builderAssistant, sqlMethod.getMethod(), languageDriver);
keyProperty = tableInfo.getKeyProperty();
keyColumn = tableInfo.getKeyColumn();
}
}
}
String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), columnScript, valuesScript);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return this.addInsertMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource, keyGenerator, keyProperty, keyColumn);
}
}

可以看到 insert 继承了 AbstractMethod 类.

1. ableInfo.getAllInsertSqlColumn()

    /**
* 获取 inset 时候字段 sql 脚本片段
* insert into table (字段) values (值)
* 位于 "字段" 部位
*
* @return sql 脚本片段
*/
public String getAllInsertSqlColumn() {
return getKeyInsertSqlColumn() + fieldList.stream().map(TableFieldInfo::getInsertSqlColumn)
.collect(joining(StringPool.NEWLINE));
}

getInsertSqlColumn() 方法, 拿列名:

    /**
* 获取 inset 时候字段 sql 脚本片段
* insert into table (字段) values (值)
* 位于 "字段" 部位
*
* @return sql 脚本片段
*/
public String getInsertSqlColumn() {
String sqlScript = column + StringPool.COMMA;
if (fieldFill == FieldFill.INSERT || fieldFill == FieldFill.INSERT_UPDATE) {
return sqlScript;
}
return convertIf(sqlScript, property);
}
getKeyInsertSqlColumn()就是根据配置看是否要拿 id , 进入sql列的拼装: 
 /**
* 获取 inset 时候主键 sql 脚本片段
* insert into table (字段) values (值)
* 位于 "字段" 部位
*
* @return sql 脚本片段
*/
public String getKeyInsertSqlColumn() {
if (StringUtils.isNotEmpty(keyColumn)) {
if (idType == IdType.AUTO) {
return StringPool.EMPTY;
}
return keyColumn + StringPool.COMMA + StringPool.NEWLINE;
}
return StringPool.EMPTY;
}

如果 id 配置了 自动生成, 则在生成 sql 的列的时候, id不参与. 也就是说, 生成的语句是 insert name, age  values(#{name}, #{age})

2. SqlScriptUtils.convertTrim()

    /**
* <p>
* 获取 带 trim 标签的脚本
* </p>
*
* @param sqlScript sql 脚本片段
* @param prefix 以...开头
* @param suffix 以...结尾
* @param prefixOverrides 干掉最前一个...
* @param suffixOverrides 干掉最后一个...
* @return trim 脚本
*/
public static String convertTrim(final String sqlScript, final String prefix, final String suffix,
final String prefixOverrides, final String suffixOverrides) {
StringBuilder sb = new StringBuilder("<trim");
if (StringUtils.isNotEmpty(prefix)) {
sb.append(" prefix=\"").append(prefix).append(StringPool.QUOTE);
}
if (StringUtils.isNotEmpty(suffix)) {
sb.append(" suffix=\"").append(suffix).append(StringPool.QUOTE);
}
if (StringUtils.isNotEmpty(prefixOverrides)) {
sb.append(" prefixOverrides=\"").append(prefixOverrides).append(StringPool.QUOTE);
}
if (StringUtils.isNotEmpty(suffixOverrides)) {
sb.append(" suffixOverrides=\"").append(suffixOverrides).append(StringPool.QUOTE);
}
return sb.append(StringPool.RIGHT_CHEV).append(StringPool.NEWLINE).append(sqlScript)
.append(StringPool.NEWLINE).append("</trim>").toString();
}

实例中, 执行完后, columnScript 的结果是:

<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name != null">name,</if>
<if test="age != null">age,</if>
<if test="email != null">email,</if>
<if test="sex != null">sex,</if>
</trim>

3. tableInfo.getAllInsertSqlProperty()

/**
* 获取所有 inset 时候插入值 sql 脚本片段
* insert into table (字段) values (值)
* 位于 "值" 部位
*
* @return sql 脚本片段
*/
public String getAllInsertSqlProperty() {
return getKeyInsertSqlProperty() + fieldList.stream().map(TableFieldInfo::getInsertSqlProperty)
.collect(joining(StringPool.NEWLINE));
} /**
* 获取 inset 时候插入值 sql 脚本片段
* insert into table (字段) values (值)
* 位于 "值" 部位
*
* @return sql 脚本片段
*/
public String getInsertSqlProperty() {
String sqlScript = SqlScriptUtils.safeParam(el) + StringPool.COMMA;
if (fieldFill == FieldFill.INSERT || fieldFill == FieldFill.INSERT_UPDATE) {
return sqlScript;
}
return convertIf(sqlScript, property);
} /**
* <p>
* 安全入参: #{入参}
* </p>
*
* @param param 入参
* @return 脚本
*/
public static String safeParam(final String param) {
return StringPool.HASH_LEFT_BRACE + param + StringPool.RIGHT_BRACE;
}

执行完之后, valuesScript 的值为:

<if test="name != null">#{name},</if>
<if test="age != null">#{age},</if>
<if test="email != null">#{email},</if>
<if test="sex != null">#{sex},</if>

拼装起来的 sql :

<script>
INSERT INTO user <trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name != null">name,</if>
<if test="age != null">age,</if>
<if test="email != null">email,</if>
<if test="sex != null">sex,</if>
</trim> VALUES <trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name != null">#{name},</if>
<if test="age != null">#{age},</if>
<if test="email != null">#{email},</if>
<if test="sex != null">#{sex},</if>
</trim>
</script>

拿到这个sql之后, 就可以创建 SqlSource 了. 然后放到  MappedStatement 里面去.

mybatis-plus - insert的更多相关文章

  1. MyBatis :Insert (返回主键、批量插入)

    一.前言    数据库操作怎能少了INSERT操作呢?下面记录MyBatis关于INSERT操作的笔记,以便日后查阅. 二.insert元素 属性详解   其属性如下: parameterType , ...

  2. Mybatis批量insert 返回主键值和foreach标签详解

    Mybatis批量insert 返回主键 Mybatis从3.3.1版本开始,支持批量插入后返回主键ID.首先对于支持自增主键的数据库使用useGenerateKeys和keyProperty,对于不 ...

  3. Mybatis 在 insert 之后想获取自增的主键 id

    记录一次傻逼的问题, 自己把自己蠢哭:Mybatis 在 insert 之后想获取自增的主键 id,但却总是返回1 错误说明: 返回的1是影响的行数,并不是自增的主键id: 想要获取自增主键id,需要 ...

  4. 【mybatis】mybatis中insert操作,返回自增id

    需求是这样的: mybatis中insert操作,返回自增id,因为这个自增id需要给后续业务用到. 原本是这样的: 将insert语句传入,正常执行insert操作,返回int永远是 0[失败] 或 ...

  5. 关于mybatis的 insert into select 命令未结束问题

    关于mybatis的 insert into select 命令未结束问题,最后以为是sql写错了,可是,在plsql运行又没问题.最后还是解决这个问题. 是设置问题. ### Cause: java ...

  6. Mybatis 在 insert 之后想获取自增的主键 id,但却总是返回1

    记录一次傻逼的问题, 自己把自己蠢哭:Mybatis 在 insert 之后想获取自增的主键 id,但却总是返回1 错误说明: 返回的1是影响的行数,并不是自增的主键id: 想要获取自增主键id,需要 ...

  7. mybatis+mysql insert添加数据后返回数据主键id

    1.根据useGeneratedKeys获取返回值,部分数据库不支持 修改mybatis xml <insert id="insertUser" useGeneratedKe ...

  8. MyBatis的Insert操作详解

    一.前言 数据库操作怎能少了INSERT操作呢?下面记录MyBatis关于INSERT操作的笔记,以便日后查阅. 二. insert元素 属性详解 其属性如下: parameterType ,入参的全 ...

  9. Mybatis 动态insert语句

    mybatis的一个比较先进的思想是把Sql语句写在了配置xml文件(也支持注解),通过配置文件的方式,免去了一般软件开发的硬编码,当业务需求改变的时候,只需要更改sql语句即可! 下面是个人在学习m ...

  10. MyBatis在insert插入操作时返回主键ID的配置

    在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数:如果业务层需要得到记录的主键时,可以通过Mapper.XML配置的方式来完成这个功能. 在 INSER ...

随机推荐

  1. 刷题84. Largest Rectangle in Histogram

    一.题目说明 题目84. Largest Rectangle in Histogram,给定n个非负整数(每个柱子宽度为1)形成柱状图,求该图的最大面积.题目难度是Hard! 二.我的解答 这是一个 ...

  2. springcloud服务已经关闭但是Eureka显示服务状态一直为UP

    问题: 最近遇到一个很奇怪的问题,就是使用springcloud的时候,服务明明已经停止,但是在eureka中一直显示此服务状态为UP,这样就导致了请求再次过来的时候被分发到已经停止的服务上,其实这是 ...

  3. Linux.CentOS下载

    1.[CentOS]centos7 稳定使用版本,centos镜像的下载 - Angel挤一挤 - 博客园.html(https://www.cnblogs.com/sxdcgaq8080/p/106 ...

  4. Codeforces Round #599 (Div. 2) D. 0-1 MST(bfs+set)

    Codeforces Round #599 (Div. 2) D. 0-1 MST Description Ujan has a lot of useless stuff in his drawers ...

  5. laravel orWhere

    场景描述 需要根据商品分类.商品名称和条形码这三个查询条件去取出结果集,这三者的关系是:商品分类 and (商品名称 or 条形码) 错误尝试 第一次写出来的代码是这样的: $goodsModel = ...

  6. MySQL 8 服务器选项配置

    查看服务器使用的默认命令选项和系统变量: mysqld --help --verbose 查看服务器当前运行时使用的系统变量和状态变量: mysql> SHOW VARIABLES; mysql ...

  7. web攻击与防御

    攻击方式 利用输出值转义漏洞 跨站脚本攻击(XSS) SQL注入攻击 OS命令注入攻击 HTTP首部注入攻击 邮件首部注入攻击 文件目录遍历攻击 利用设置或设计缺陷 强制游览 开放重定向 不正确的错误 ...

  8. Java虚拟内存(栈、堆)

    一.java虚拟的内存可以分为几种 1. 第一种 栈(stack) 栈的特点 1.1 栈描述的是方法执行的内存模型,每个方法都被调用都会创建一个栈(存储局部变量.操作数. 方法出口等) 1.2 JVM ...

  9. python3-cookbook笔记:第二章 字符串和文本

    python3-cookbook中每个小节以问题.解决方案和讨论三个部分探讨了Python3在某类问题中的最优解决方式,或者说是探讨Python3本身的数据结构.函数.类等特性在某类问题上如何更好地使 ...

  10. HDU1408 - 盐水的故事

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1408 解题思路:主要考虑最后一滴可能不满足D毫升,但仍算1秒.另外还要注意浮点数的比较. #inclu ...