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

  • 相关阅读:
    loaded some nib but the view outlet was not set
    指标评比
    IOS DEVELOP FOR DUMMIES
    软件测试题二
    javascript select
    DOM节点类型详解
    mysql操作
    UVA 10055
    solutions for 'No Suitable Driver Found For Jdbc'
    解决git中文乱码问题
  • 原文地址:https://www.cnblogs.com/elvinle/p/12321680.html
Copyright © 2020-2023  润新知