mybatis-plus - insert
一. 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的更多相关文章
- MyBatis :Insert (返回主键、批量插入)
一.前言 数据库操作怎能少了INSERT操作呢?下面记录MyBatis关于INSERT操作的笔记,以便日后查阅. 二.insert元素 属性详解 其属性如下: parameterType , ...
- Mybatis批量insert 返回主键值和foreach标签详解
Mybatis批量insert 返回主键 Mybatis从3.3.1版本开始,支持批量插入后返回主键ID.首先对于支持自增主键的数据库使用useGenerateKeys和keyProperty,对于不 ...
- Mybatis 在 insert 之后想获取自增的主键 id
记录一次傻逼的问题, 自己把自己蠢哭:Mybatis 在 insert 之后想获取自增的主键 id,但却总是返回1 错误说明: 返回的1是影响的行数,并不是自增的主键id: 想要获取自增主键id,需要 ...
- 【mybatis】mybatis中insert操作,返回自增id
需求是这样的: mybatis中insert操作,返回自增id,因为这个自增id需要给后续业务用到. 原本是这样的: 将insert语句传入,正常执行insert操作,返回int永远是 0[失败] 或 ...
- 关于mybatis的 insert into select 命令未结束问题
关于mybatis的 insert into select 命令未结束问题,最后以为是sql写错了,可是,在plsql运行又没问题.最后还是解决这个问题. 是设置问题. ### Cause: java ...
- Mybatis 在 insert 之后想获取自增的主键 id,但却总是返回1
记录一次傻逼的问题, 自己把自己蠢哭:Mybatis 在 insert 之后想获取自增的主键 id,但却总是返回1 错误说明: 返回的1是影响的行数,并不是自增的主键id: 想要获取自增主键id,需要 ...
- mybatis+mysql insert添加数据后返回数据主键id
1.根据useGeneratedKeys获取返回值,部分数据库不支持 修改mybatis xml <insert id="insertUser" useGeneratedKe ...
- MyBatis的Insert操作详解
一.前言 数据库操作怎能少了INSERT操作呢?下面记录MyBatis关于INSERT操作的笔记,以便日后查阅. 二. insert元素 属性详解 其属性如下: parameterType ,入参的全 ...
- Mybatis 动态insert语句
mybatis的一个比较先进的思想是把Sql语句写在了配置xml文件(也支持注解),通过配置文件的方式,免去了一般软件开发的硬编码,当业务需求改变的时候,只需要更改sql语句即可! 下面是个人在学习m ...
- MyBatis在insert插入操作时返回主键ID的配置
在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数:如果业务层需要得到记录的主键时,可以通过Mapper.XML配置的方式来完成这个功能. 在 INSER ...
随机推荐
- 刷题84. Largest Rectangle in Histogram
一.题目说明 题目84. Largest Rectangle in Histogram,给定n个非负整数(每个柱子宽度为1)形成柱状图,求该图的最大面积.题目难度是Hard! 二.我的解答 这是一个 ...
- springcloud服务已经关闭但是Eureka显示服务状态一直为UP
问题: 最近遇到一个很奇怪的问题,就是使用springcloud的时候,服务明明已经停止,但是在eureka中一直显示此服务状态为UP,这样就导致了请求再次过来的时候被分发到已经停止的服务上,其实这是 ...
- Linux.CentOS下载
1.[CentOS]centos7 稳定使用版本,centos镜像的下载 - Angel挤一挤 - 博客园.html(https://www.cnblogs.com/sxdcgaq8080/p/106 ...
- 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 ...
- laravel orWhere
场景描述 需要根据商品分类.商品名称和条形码这三个查询条件去取出结果集,这三者的关系是:商品分类 and (商品名称 or 条形码) 错误尝试 第一次写出来的代码是这样的: $goodsModel = ...
- MySQL 8 服务器选项配置
查看服务器使用的默认命令选项和系统变量: mysqld --help --verbose 查看服务器当前运行时使用的系统变量和状态变量: mysql> SHOW VARIABLES; mysql ...
- web攻击与防御
攻击方式 利用输出值转义漏洞 跨站脚本攻击(XSS) SQL注入攻击 OS命令注入攻击 HTTP首部注入攻击 邮件首部注入攻击 文件目录遍历攻击 利用设置或设计缺陷 强制游览 开放重定向 不正确的错误 ...
- Java虚拟内存(栈、堆)
一.java虚拟的内存可以分为几种 1. 第一种 栈(stack) 栈的特点 1.1 栈描述的是方法执行的内存模型,每个方法都被调用都会创建一个栈(存储局部变量.操作数. 方法出口等) 1.2 JVM ...
- python3-cookbook笔记:第二章 字符串和文本
python3-cookbook中每个小节以问题.解决方案和讨论三个部分探讨了Python3在某类问题中的最优解决方式,或者说是探讨Python3本身的数据结构.函数.类等特性在某类问题上如何更好地使 ...
- HDU1408 - 盐水的故事
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1408 解题思路:主要考虑最后一滴可能不满足D毫升,但仍算1秒.另外还要注意浮点数的比较. #inclu ...