All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.bootx.table.modify.mysql.service.MySqlColumnInfoService Maven / Gradle / Ivy

There is a newer version: 1.5.5
Show newest version
package cn.bootx.table.modify.mysql.service;

import cn.bootx.table.modify.mysql.entity.MySqlEntityColumn;
import cn.bootx.table.modify.mysql.entity.MySqlModifyMap;
import cn.bootx.table.modify.mysql.entity.MySqlTableColumn;
import cn.bootx.table.modify.mysql.handler.MySqlTableModifyDao;
import cn.bootx.table.modify.mysql.util.MySqlInfoUtil;
import cn.bootx.table.modify.utils.ColumnUtils;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * MySQL 字段处理
 * @author xxm
 * @since 2023/4/13
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class MySqlColumnInfoService {
    private final MySqlTableModifyDao mySqlTableModifyDao;

    /**
     * 获取建表的字段
     */
    public void getCreateColumn(Class clas,  MySqlModifyMap baseTableMap){

        // 获取entity的tableName
        String tableName = ColumnUtils.getTableName(clas);

        // 用于实体类配置的全部字段
        List entityColumns;
        try {
            entityColumns = MySqlInfoUtil.getEntityColumns(clas).stream()
                    .filter(o->!o.isDelete())
                    .collect(Collectors.toList());
            baseTableMap.getAddColumns().put(tableName,entityColumns);
        } catch (Exception e) {
            log.error("表:{},初始化字段结构失败!", tableName);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 获取要更新的字段
     */
    public void getModifyColumn(Class clas,  MySqlModifyMap baseTableMap) {
        // 获取entity的tableName
        String tableName = ColumnUtils.getTableName(clas);

        // 用于实体类配置的全部字段
        List entityColumns;
        try {
            entityColumns = MySqlInfoUtil.getEntityColumns(clas);
        }
        catch (Exception e) {
            log.error("表:{},初始化字段结构失败!", tableName);
            throw new RuntimeException(e.getMessage());
        }
        // 数据库表结构
        List tableColumns = mySqlTableModifyDao.findColumnByTableName(tableName);
        // 是否追加模式
        boolean append = ColumnUtils.isAppend(clas);


        // 找出增加的字段
        List addColumns = getAddColumns(entityColumns, tableColumns);
        if (!addColumns.isEmpty()) {
            baseTableMap.getAddColumns().put(tableName, addColumns);
        }
        // 找出删除的字段
        List dropColumns = getDropColumns(entityColumns, tableColumns, append);
        if (!dropColumns.isEmpty()) {
            baseTableMap.getDropColumns().put(tableName, dropColumns);
        }
        // 找出更新的字段
        List updateColumns = getUpdateColumns(entityColumns,tableColumns);
        if (!updateColumns.isEmpty()) {
            baseTableMap.getUpdateColumns().put(tableName, updateColumns);
        }
    }

    /**
     * 根据数据库中表的结构和entity中表的结构对比找出新增的字段
     *
     * @param entityColumns entity中的所有字段
     * @param tableColumns  数据库中的结构
     * @return 新增的字段
     */
    private List getAddColumns(List entityColumns, List tableColumns) {

        List tableColumnNames = tableColumns.stream()
                .map(MySqlTableColumn::getColumnName)
                .map(String::toLowerCase)
                .collect(Collectors.toList());
        // 数据库中不存在, 进行添加
        return entityColumns.stream()
                .filter(o->!o.isDelete())
                .filter(column->!tableColumnNames.contains(column.getName().toLowerCase()))
                .collect(Collectors.toList());
    }

    /**
     * 根据数据库中表的结构和entity中表的结构对比找出删除的字段
     *
     * @param entityColumns entity中的所有字段
     * @param tableColumns  数据库中的结构
     * @param append 是否追加模式
     */
    private List getDropColumns(List entityColumns, List tableColumns, boolean append) {
        // 是否追加模式
        if (append) {
            // 删除标记删除的字段
            List deletes = entityColumns.stream()
                    .filter(MySqlEntityColumn::isDelete)
                    .map(MySqlEntityColumn::getName)
                    .map(String::toLowerCase)
                    .collect(Collectors.toList());
            // 比对数据库字段, 把未删除的字段筛选出来
            return tableColumns.stream()
                    .map(MySqlTableColumn::getColumnName)
                    .map(String::toLowerCase)
                    .filter(columnName -> deletes.contains(columnName.toLowerCase()))
                    .collect(Collectors.toList());
        } else {
            // 筛选出来不需要进行删除的字段
            List entityColumnNames = entityColumns.stream()
                    .filter(o->!o.isDelete())
                    .map(MySqlEntityColumn::getName)
                    .map(String::toLowerCase)
                    .collect(Collectors.toList());
            // 比对数据库的配置将,找出需要删除的字段, 进行删除
            return tableColumns.stream()
                    .map(MySqlTableColumn::getColumnName)
                    .filter(columnName -> !entityColumnNames.contains(columnName.toLowerCase()))
                    .collect(Collectors.toList());
        }
    }

    /**
     * 根据数据库中表的结构和entity中表的结构对比找出修改类型默认值等属性的字段
     *
     * @param entityColumns entity中的所有字段
     * @param tableColumns  数据库中的结构
     * @return 需要修改的字段
     */
    private List getUpdateColumns(List entityColumns, List tableColumns) {
        // 现有的数据库字段配置
        List tableIndexNames = tableColumns.stream()
                .map(MySqlTableColumn::getColumnName)
                .map(String::toLowerCase)
                .distinct()
                .collect(Collectors.toList());

        // 现有的数据库字段配置 MAP
        val tableColumnMap = tableColumns.stream()
                .collect(Collectors.toMap(column -> column.getColumnName().toLowerCase(), Function.identity()));

        // 把两者都有的字段筛选出来进行对比, 筛选出来有不同的字段
        return entityColumns.stream()
                .filter(o->!o.isDelete())
                .filter(column->tableIndexNames.contains(column.getName().toLowerCase()))
                .filter(entityColumn->!compareColumn(tableColumnMap.get(entityColumn.getName().toLowerCase()),entityColumn))
                .collect(Collectors.toList());

    }


    /**
     * 判断字段配置是否一致
     * @param tableColumn 表行信息
     * @param entityColumn 实体配行信息
     * @return 是否需要变动 true 需要更新
     */
    private boolean compareColumn(MySqlTableColumn tableColumn, MySqlEntityColumn entityColumn){

        // 验证类型
        if (!tableColumn.getDataType().equalsIgnoreCase(entityColumn.getFieldType())) {
            return false;
        }
        // 验证长度和小数点位数
        String typeAndLength = entityColumn.getFieldType().toLowerCase();
        if (entityColumn.getParamCount() == 1) {
            // 拼接出类型加长度,比如varchar(1)
            typeAndLength = typeAndLength + "(" + entityColumn.getLength() + ")";
        }
        else if (entityColumn.getParamCount() == 2) {
            // 拼接出类型加长度,比如varchar(1)
            typeAndLength = typeAndLength + "(" + entityColumn.getLength() + ","
                    + entityColumn.getPrecision() + ")";
        }

        // 判断类型+长度是否相同
        if (!tableColumn.getColumnType().toLowerCase().equals(typeAndLength)) {
            return false;
        }

        // 验证自增 数据库自增, 实体类不自增
        if ("auto_increment".equals(tableColumn.getExtra()) && !entityColumn.isAutoIncrement()) {
            return false;
        }
        // 验证自增 数据库不自增, 实体类自增
        if (!"auto_increment".equals(tableColumn.getExtra()) && entityColumn.isAutoIncrement()) {
            return false;
        }
        // 验证默认值控制是否为空
        if (StrUtil.isBlank(entityColumn.getDefaultValue()) != StrUtil.isBlank(tableColumn.getColumnDefault())) {
            return false;
        }
        // entityColumn默认值需要去除两侧单引号,然后比对默认值是否一致
        if (StrUtil.isNotBlank(entityColumn.getDefaultValue())){
            String entityDefaultValue = StrUtil.trim(entityColumn.getDefaultValue(), 0, character -> character.toString().equals("'"));
            if (!Objects.equals(entityDefaultValue,tableColumn.getColumnDefault())){
                return false;
            }
        }
        // 验证是否可以为null
        if (tableColumn.getIsNullable().equals("NO") && !entityColumn.isKey()) {
            if (entityColumn.isFieldIsNull()) {
                return false;
            }
        }
        // 验证是否可以为null
        else if (tableColumn.getIsNullable().equals("YES") && !entityColumn.isKey()) {
            if (!entityColumn.isFieldIsNull()) {
                return false;
            }
        }
        // 8.验证注释是否发生了变动
        if (!Objects.equals(tableColumn.getColumnComment(),entityColumn.getComment())) {
            return false;
        }

        return true;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy