zoukankan      html  css  js  c++  java
  • mybatis-plus

    一. 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 里面去.

  • 相关阅读:
    wxGlade: a GUI builder for wxWidgets/wxPython
    wxPython or PyQt or PySide哪一个比较好
    wxpython学习笔记
    C++实现发送HTTP请求 CoderZh 博客园
    Lucene如何分布式(WWW与Lucene服务器分离)
    MVC中一个表单实现多个提交按钮(一个action搞定添删改)
    何为.Net Remoting
    Lucene实用的分词匹配
    我心中的核心组件(可插拔的AOP)~第十四回 全文检索架构~终于设计了一个自己满意的Lucene架构
    【学习opencv第五篇】霍夫线变换
  • 原文地址:https://www.cnblogs.com/elvinle/p/12321680.html
Copyright © 2011-2022 走看看