【功能修复】代码生成:代同步数据库结构之后字段顺序混乱的问题

This commit is contained in:
YunaiV 2024-09-29 07:41:35 +08:00
parent e630cea3bc
commit 42b7946685
4 changed files with 32 additions and 17 deletions

View File

@ -134,6 +134,11 @@ public class RandomUtils {
@SafeVarargs @SafeVarargs
public static <T> List<T> randomPojoList(Class<T> clazz, Consumer<T>... consumers) { public static <T> List<T> randomPojoList(Class<T> clazz, Consumer<T>... consumers) {
int size = RandomUtil.randomInt(1, RANDOM_COLLECTION_LENGTH); int size = RandomUtil.randomInt(1, RANDOM_COLLECTION_LENGTH);
return randomPojoList(clazz, size, consumers);
}
@SafeVarargs
public static <T> List<T> randomPojoList(Class<T> clazz, int size, Consumer<T>... consumers) {
return Stream.iterate(0, i -> i).limit(size).map(o -> randomPojo(clazz, consumers)) return Stream.iterate(0, i -> i).limit(size).map(o -> randomPojo(clazz, consumers))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }

View File

@ -13,7 +13,7 @@ public interface CodegenColumnMapper extends BaseMapperX<CodegenColumnDO> {
default List<CodegenColumnDO> selectListByTableId(Long tableId) { default List<CodegenColumnDO> selectListByTableId(Long tableId) {
return selectList(new LambdaQueryWrapperX<CodegenColumnDO>() return selectList(new LambdaQueryWrapperX<CodegenColumnDO>()
.eq(CodegenColumnDO::getTableId, tableId) .eq(CodegenColumnDO::getTableId, tableId)
.orderByAsc(CodegenColumnDO::getId)); .orderByAsc(CodegenColumnDO::getOrdinalPosition));
} }
default void deleteListByTableId(Long tableId) { default void deleteListByTableId(Long tableId) {

View File

@ -22,13 +22,14 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import com.baomidou.mybatisplus.generator.config.po.TableField; import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo; import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import jakarta.annotation.Resource;
import java.util.*; import java.util.*;
import java.util.function.BiPredicate; import java.util.function.BiPredicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
@ -179,11 +180,18 @@ public class CodegenServiceImpl implements CodegenService {
&& tableField.getMetaInfo().isNullable() == codegenColumn.getNullable() && tableField.getMetaInfo().isNullable() == codegenColumn.getNullable()
&& tableField.isKeyFlag() == codegenColumn.getPrimaryKey() && tableField.isKeyFlag() == codegenColumn.getPrimaryKey()
&& tableField.getComment().equals(codegenColumn.getColumnComment()); && tableField.getComment().equals(codegenColumn.getColumnComment());
Set<String> modifyFieldNames = tableFields.stream() Set<String> modifyFieldNames = IntStream.range(0, tableFields.size()).mapToObj(index -> {
.filter(tableField -> codegenColumnDOMap.get(tableField.getColumnName()) != null TableField tableField = tableFields.get(index);
&& !primaryKeyPredicate.test(tableField, codegenColumnDOMap.get(tableField.getColumnName()))) String columnName = tableField.getColumnName();
.map(TableField::getColumnName) CodegenColumnDO codegenColumn = codegenColumnDOMap.get(columnName);
.collect(Collectors.toSet()); if (codegenColumn == null) {
return null;
}
if (!primaryKeyPredicate.test(tableField, codegenColumn) || codegenColumn.getOrdinalPosition() != index) {
return columnName;
}
return null;
}).filter(Objects::nonNull).collect(Collectors.toSet());
// 3.2 计算需要删除的字段 // 3.2 计算需要删除的字段
Set<String> tableFieldNames = convertSet(tableFields, TableField::getName); Set<String> tableFieldNames = convertSet(tableFields, TableField::getName);
Set<Long> deleteColumnIds = codegenColumns.stream() Set<Long> deleteColumnIds = codegenColumns.stream()

View File

@ -24,12 +24,11 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.baomidou.mybatisplus.generator.config.po.TableField; import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo; import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import org.junit.jupiter.api.Disabled; import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import jakarta.annotation.Resource;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -234,17 +233,16 @@ public class CodegenServiceImplTest extends BaseDbUnitTest {
} }
@Test @Test
@Disabled // TODO @芋艿这个单测会随机性失败需要定位下
public void testSyncCodegenFromDB() { public void testSyncCodegenFromDB() {
// mock 数据CodegenTableDO // mock 数据CodegenTableDO
CodegenTableDO table = randomPojo(CodegenTableDO.class, o -> o.setTableName("t_yunai") CodegenTableDO table = randomPojo(CodegenTableDO.class, o -> o.setTableName("t_yunai")
.setDataSourceConfigId(1L).setScene(CodegenSceneEnum.ADMIN.getScene())); .setDataSourceConfigId(1L).setScene(CodegenSceneEnum.ADMIN.getScene()));
codegenTableMapper.insert(table); codegenTableMapper.insert(table);
CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId()) CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
.setColumnName("id")); .setColumnName("id").setPrimaryKey(true).setOrdinalPosition(0));
codegenColumnMapper.insert(column01); codegenColumnMapper.insert(column01);
CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId()) CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
.setColumnName("name")); .setColumnName("name").setOrdinalPosition(1));
codegenColumnMapper.insert(column02); codegenColumnMapper.insert(column02);
// 准备参数 // 准备参数
Long tableId = table.getId(); Long tableId = table.getId();
@ -263,7 +261,7 @@ public class CodegenServiceImplTest extends BaseDbUnitTest {
when(databaseTableService.getTable(eq(1L), eq("t_yunai"))) when(databaseTableService.getTable(eq(1L), eq("t_yunai")))
.thenReturn(tableInfo); .thenReturn(tableInfo);
// mock 方法CodegenTableDO // mock 方法CodegenTableDO
List<CodegenColumnDO> newColumns = randomPojoList(CodegenColumnDO.class); List<CodegenColumnDO> newColumns = randomPojoList(CodegenColumnDO.class, 2);
when(codegenBuilder.buildColumns(eq(table.getId()), argThat(tableFields -> { when(codegenBuilder.buildColumns(eq(table.getId()), argThat(tableFields -> {
assertEquals(2, tableFields.size()); assertEquals(2, tableFields.size());
assertSame(tableInfo.getFields(), tableFields); assertSame(tableInfo.getFields(), tableFields);
@ -457,9 +455,11 @@ public class CodegenServiceImplTest extends BaseDbUnitTest {
.setTemplateType(CodegenTemplateTypeEnum.ONE.getType())); .setTemplateType(CodegenTemplateTypeEnum.ONE.getType()));
codegenTableMapper.insert(table); codegenTableMapper.insert(table);
// mock 数据CodegenColumnDO // mock 数据CodegenColumnDO
CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())); CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
.setOrdinalPosition(1));
codegenColumnMapper.insert(column01); codegenColumnMapper.insert(column01);
CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())); CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
.setOrdinalPosition(2));
codegenColumnMapper.insert(column02); codegenColumnMapper.insert(column02);
// mock 执行生成 // mock 执行生成
Map<String, String> codes = MapUtil.of(randomString(), randomString()); Map<String, String> codes = MapUtil.of(randomString(), randomString());
@ -486,9 +486,11 @@ public class CodegenServiceImplTest extends BaseDbUnitTest {
.setTemplateType(CodegenTemplateTypeEnum.MASTER_NORMAL.getType())); .setTemplateType(CodegenTemplateTypeEnum.MASTER_NORMAL.getType()));
codegenTableMapper.insert(table); codegenTableMapper.insert(table);
// mock 数据CodegenColumnDO // mock 数据CodegenColumnDO
CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())); CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
.setOrdinalPosition(1));
codegenColumnMapper.insert(column01); codegenColumnMapper.insert(column01);
CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())); CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
.setOrdinalPosition(2));
codegenColumnMapper.insert(column02); codegenColumnMapper.insert(column02);
// mock 数据sub CodegenTableDO // mock 数据sub CodegenTableDO
CodegenTableDO subTable = randomPojo(CodegenTableDO.class, CodegenTableDO subTable = randomPojo(CodegenTableDO.class,