一. insert

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

  1. /**
  2. * <p>
  3. * 根据 ID 删除
  4. * </p>
  5. *
  6. * @author hubin
  7. * @since 2018-04-06
  8. */
  9. public class Insert extends AbstractMethod {
  10.  
  11. @Override
  12. public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
  13. KeyGenerator keyGenerator = new NoKeyGenerator();
  14. SqlMethod sqlMethod = SqlMethod.INSERT_ONE;
  15. String columnScript = SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlColumn(),
  16. StringPool.LEFT_BRACKET, StringPool.RIGHT_BRACKET, null, StringPool.COMMA);
  17. String valuesScript = SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlProperty(),
  18. StringPool.LEFT_BRACKET, StringPool.RIGHT_BRACKET, null, StringPool.COMMA);
  19. String keyProperty = null;
  20. String keyColumn = null;
  21. // 表包含主键处理逻辑,如果不包含主键当普通字段处理
  22. if (StringUtils.isNotEmpty(tableInfo.getKeyProperty())) {
  23. if (tableInfo.getIdType() == IdType.AUTO) {
  24. /** 自增主键 */
  25. keyGenerator = new Jdbc3KeyGenerator();
  26. keyProperty = tableInfo.getKeyProperty();
  27. keyColumn = tableInfo.getKeyColumn();
  28. } else {
  29. if (null != tableInfo.getKeySequence()) {
  30. keyGenerator = TableInfoHelper.genKeyGenerator(tableInfo, builderAssistant, sqlMethod.getMethod(), languageDriver);
  31. keyProperty = tableInfo.getKeyProperty();
  32. keyColumn = tableInfo.getKeyColumn();
  33. }
  34. }
  35. }
  36. String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), columnScript, valuesScript);
  37. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
  38. return this.addInsertMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource, keyGenerator, keyProperty, keyColumn);
  39. }
  40. }

可以看到 insert 继承了 AbstractMethod 类.

1. ableInfo.getAllInsertSqlColumn()

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

getInsertSqlColumn() 方法, 拿列名:

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

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

2. SqlScriptUtils.convertTrim()

  1. /**
  2. * <p>
  3. * 获取 带 trim 标签的脚本
  4. * </p>
  5. *
  6. * @param sqlScript sql 脚本片段
  7. * @param prefix 以...开头
  8. * @param suffix 以...结尾
  9. * @param prefixOverrides 干掉最前一个...
  10. * @param suffixOverrides 干掉最后一个...
  11. * @return trim 脚本
  12. */
  13. public static String convertTrim(final String sqlScript, final String prefix, final String suffix,
  14. final String prefixOverrides, final String suffixOverrides) {
  15. StringBuilder sb = new StringBuilder("<trim");
  16. if (StringUtils.isNotEmpty(prefix)) {
  17. sb.append(" prefix=\"").append(prefix).append(StringPool.QUOTE);
  18. }
  19. if (StringUtils.isNotEmpty(suffix)) {
  20. sb.append(" suffix=\"").append(suffix).append(StringPool.QUOTE);
  21. }
  22. if (StringUtils.isNotEmpty(prefixOverrides)) {
  23. sb.append(" prefixOverrides=\"").append(prefixOverrides).append(StringPool.QUOTE);
  24. }
  25. if (StringUtils.isNotEmpty(suffixOverrides)) {
  26. sb.append(" suffixOverrides=\"").append(suffixOverrides).append(StringPool.QUOTE);
  27. }
  28. return sb.append(StringPool.RIGHT_CHEV).append(StringPool.NEWLINE).append(sqlScript)
  29. .append(StringPool.NEWLINE).append("</trim>").toString();
  30. }

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

  1. <trim prefix="(" suffix=")" suffixOverrides=",">
  2. <if test="name != null">name,</if>
  3. <if test="age != null">age,</if>
  4. <if test="email != null">email,</if>
  5. <if test="sex != null">sex,</if>
  6. </trim>

3. tableInfo.getAllInsertSqlProperty()

  1. /**
  2. * 获取所有 inset 时候插入值 sql 脚本片段
  3. * insert into table (字段) values (值)
  4. * 位于 "值" 部位
  5. *
  6. * @return sql 脚本片段
  7. */
  8. public String getAllInsertSqlProperty() {
  9. return getKeyInsertSqlProperty() + fieldList.stream().map(TableFieldInfo::getInsertSqlProperty)
  10. .collect(joining(StringPool.NEWLINE));
  11. }
  12.  
  13. /**
  14. * 获取 inset 时候插入值 sql 脚本片段
  15. * insert into table (字段) values (值)
  16. * 位于 "值" 部位
  17. *
  18. * @return sql 脚本片段
  19. */
  20. public String getInsertSqlProperty() {
  21. String sqlScript = SqlScriptUtils.safeParam(el) + StringPool.COMMA;
  22. if (fieldFill == FieldFill.INSERT || fieldFill == FieldFill.INSERT_UPDATE) {
  23. return sqlScript;
  24. }
  25. return convertIf(sqlScript, property);
  26. }
  27.  
  28. /**
  29. * <p>
  30. * 安全入参: #{入参}
  31. * </p>
  32. *
  33. * @param param 入参
  34. * @return 脚本
  35. */
  36. public static String safeParam(final String param) {
  37. return StringPool.HASH_LEFT_BRACE + param + StringPool.RIGHT_BRACE;
  38. }

执行完之后, valuesScript 的值为:

  1. <if test="name != null">#{name},</if>
  2. <if test="age != null">#{age},</if>
  3. <if test="email != null">#{email},</if>
  4. <if test="sex != null">#{sex},</if>

拼装起来的 sql :

  1. <script>
  2. INSERT INTO user <trim prefix="(" suffix=")" suffixOverrides=",">
  3. <if test="name != null">name,</if>
  4. <if test="age != null">age,</if>
  5. <if test="email != null">email,</if>
  6. <if test="sex != null">sex,</if>
  7. </trim> VALUES <trim prefix="(" suffix=")" suffixOverrides=",">
  8. <if test="name != null">#{name},</if>
  9. <if test="age != null">#{age},</if>
  10. <if test="email != null">#{email},</if>
  11. <if test="sex != null">#{sex},</if>
  12. </trim>
  13. </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. 一个最简单的Dockfile实践

    一:一个Dockerfile文件 FROM bash COPY . /usr/jinliang/ WORKDIR /usr/jinliang/ CMD [ "sh", " ...

  2. em和rem区别

    em大小依据父元素的字体大小的倍数 rem大小依据与根元素,即html标签的font-size大小

  3. 分布式配置中心:Spring Cloud Config

    最近在学习Spring Cloud的知识,现将分布式配置中心:Spring Cloud Config的相关知识笔记整理如下.[采用 oneNote格式排版]

  4. kettle文本文件写入数据库,简单进行数据清洗

    使用kettle7.0,java8.0,Navicat,实验数据使用全国肺炎2月24日的数据 1.建立关系 2.创建连接 如果是第一次连接,可能会出现连接不上的情况,这时候可能情况是没有将Mysql的 ...

  5. jQuery---委托事件原理

    jQuery事件发展历程 事件发展历程:从简单事件,到bind,到委托事件,到on事件绑定 //简单事件,给自己注册的事件 $("div").click(function () { ...

  6. memcached的安装、常用命令以及在实际开发中的案例

    Memcached注意缺乏安全认证以及安全管制需要将Memcached服务器放置在防火墙(iptables)之后 Linux平台 (CentOS)安装Memcached 安装依赖yum -y inst ...

  7. java静态初始化块的执行顺序

    先来观察下面的代码 package trr; class Root { static{ System.out.println("Root的静态初始化块"); } { System. ...

  8. c#获取所有枚举

    获取所有的枚举 1.将所有的枚举单独成一个项目 2.通Assembly加载程序集 3.通过Assembly对象的GetTypes获取所有的枚举类型 4.通过Enum.GetValues可以得到枚举的所 ...

  9. Beamer加入背景图片

    在Beamer中加入背景图片只要把背景重新设置一下: \setbeamertemplate{background}{\includegraphics[height=\paperheight]{bg}} ...

  10. Wannafly Camp 2020 Day 2D 卡拉巴什的字符串 - 后缀自动机

    动态维护任意两个后缀的lcp集合的mex,支持在串末尾追加字符. Solution 考虑在 SAM 上求两个后缀的 LCP 的过程,无非就是找它们在 fail 树上的 LCA,那么 LCP 长度就是这 ...