Commit 42b7946685bdfb89f94c613e70f890425a94aaf1

Authored by YunaiV
1 parent e630cea3

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

yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/RandomUtils.java
@@ -134,6 +134,11 @@ public class RandomUtils { @@ -134,6 +134,11 @@ public class RandomUtils {
134 @SafeVarargs 134 @SafeVarargs
135 public static <T> List<T> randomPojoList(Class<T> clazz, Consumer<T>... consumers) { 135 public static <T> List<T> randomPojoList(Class<T> clazz, Consumer<T>... consumers) {
136 int size = RandomUtil.randomInt(1, RANDOM_COLLECTION_LENGTH); 136 int size = RandomUtil.randomInt(1, RANDOM_COLLECTION_LENGTH);
  137 + return randomPojoList(clazz, size, consumers);
  138 + }
  139 +
  140 + @SafeVarargs
  141 + public static <T> List<T> randomPojoList(Class<T> clazz, int size, Consumer<T>... consumers) {
137 return Stream.iterate(0, i -> i).limit(size).map(o -> randomPojo(clazz, consumers)) 142 return Stream.iterate(0, i -> i).limit(size).map(o -> randomPojo(clazz, consumers))
138 .collect(Collectors.toList()); 143 .collect(Collectors.toList());
139 } 144 }
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/codegen/CodegenColumnMapper.java
@@ -13,7 +13,7 @@ public interface CodegenColumnMapper extends BaseMapperX&lt;CodegenColumnDO&gt; { @@ -13,7 +13,7 @@ public interface CodegenColumnMapper extends BaseMapperX&lt;CodegenColumnDO&gt; {
13 default List<CodegenColumnDO> selectListByTableId(Long tableId) { 13 default List<CodegenColumnDO> selectListByTableId(Long tableId) {
14 return selectList(new LambdaQueryWrapperX<CodegenColumnDO>() 14 return selectList(new LambdaQueryWrapperX<CodegenColumnDO>()
15 .eq(CodegenColumnDO::getTableId, tableId) 15 .eq(CodegenColumnDO::getTableId, tableId)
16 - .orderByAsc(CodegenColumnDO::getId)); 16 + .orderByAsc(CodegenColumnDO::getOrdinalPosition));
17 } 17 }
18 18
19 default void deleteListByTableId(Long tableId) { 19 default void deleteListByTableId(Long tableId) {
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenServiceImpl.java
@@ -22,13 +22,14 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi; @@ -22,13 +22,14 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
22 import com.baomidou.mybatisplus.generator.config.po.TableField; 22 import com.baomidou.mybatisplus.generator.config.po.TableField;
23 import com.baomidou.mybatisplus.generator.config.po.TableInfo; 23 import com.baomidou.mybatisplus.generator.config.po.TableInfo;
24 import com.google.common.annotations.VisibleForTesting; 24 import com.google.common.annotations.VisibleForTesting;
  25 +import jakarta.annotation.Resource;
25 import org.springframework.stereotype.Service; 26 import org.springframework.stereotype.Service;
26 import org.springframework.transaction.annotation.Transactional; 27 import org.springframework.transaction.annotation.Transactional;
27 28
28 -import jakarta.annotation.Resource;  
29 import java.util.*; 29 import java.util.*;
30 import java.util.function.BiPredicate; 30 import java.util.function.BiPredicate;
31 import java.util.stream.Collectors; 31 import java.util.stream.Collectors;
  32 +import java.util.stream.IntStream;
32 33
33 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 34 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
34 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; 35 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
@@ -179,11 +180,18 @@ public class CodegenServiceImpl implements CodegenService { @@ -179,11 +180,18 @@ public class CodegenServiceImpl implements CodegenService {
179 && tableField.getMetaInfo().isNullable() == codegenColumn.getNullable() 180 && tableField.getMetaInfo().isNullable() == codegenColumn.getNullable()
180 && tableField.isKeyFlag() == codegenColumn.getPrimaryKey() 181 && tableField.isKeyFlag() == codegenColumn.getPrimaryKey()
181 && tableField.getComment().equals(codegenColumn.getColumnComment()); 182 && tableField.getComment().equals(codegenColumn.getColumnComment());
182 - Set<String> modifyFieldNames = tableFields.stream()  
183 - .filter(tableField -> codegenColumnDOMap.get(tableField.getColumnName()) != null  
184 - && !primaryKeyPredicate.test(tableField, codegenColumnDOMap.get(tableField.getColumnName())))  
185 - .map(TableField::getColumnName)  
186 - .collect(Collectors.toSet()); 183 + Set<String> modifyFieldNames = IntStream.range(0, tableFields.size()).mapToObj(index -> {
  184 + TableField tableField = tableFields.get(index);
  185 + String columnName = tableField.getColumnName();
  186 + CodegenColumnDO codegenColumn = codegenColumnDOMap.get(columnName);
  187 + if (codegenColumn == null) {
  188 + return null;
  189 + }
  190 + if (!primaryKeyPredicate.test(tableField, codegenColumn) || codegenColumn.getOrdinalPosition() != index) {
  191 + return columnName;
  192 + }
  193 + return null;
  194 + }).filter(Objects::nonNull).collect(Collectors.toSet());
187 // 3.2 计算需要【删除】的字段 195 // 3.2 计算需要【删除】的字段
188 Set<String> tableFieldNames = convertSet(tableFields, TableField::getName); 196 Set<String> tableFieldNames = convertSet(tableFields, TableField::getName);
189 Set<Long> deleteColumnIds = codegenColumns.stream() 197 Set<Long> deleteColumnIds = codegenColumns.stream()
yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenServiceImplTest.java
@@ -24,12 +24,11 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi; @@ -24,12 +24,11 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
24 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 24 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
25 import com.baomidou.mybatisplus.generator.config.po.TableField; 25 import com.baomidou.mybatisplus.generator.config.po.TableField;
26 import com.baomidou.mybatisplus.generator.config.po.TableInfo; 26 import com.baomidou.mybatisplus.generator.config.po.TableInfo;
27 -import org.junit.jupiter.api.Disabled; 27 +import jakarta.annotation.Resource;
28 import org.junit.jupiter.api.Test; 28 import org.junit.jupiter.api.Test;
29 import org.springframework.boot.test.mock.mockito.MockBean; 29 import org.springframework.boot.test.mock.mockito.MockBean;
30 import org.springframework.context.annotation.Import; 30 import org.springframework.context.annotation.Import;
31 31
32 -import jakarta.annotation.Resource;  
33 import java.util.Arrays; 32 import java.util.Arrays;
34 import java.util.Collections; 33 import java.util.Collections;
35 import java.util.List; 34 import java.util.List;
@@ -234,17 +233,16 @@ public class CodegenServiceImplTest extends BaseDbUnitTest { @@ -234,17 +233,16 @@ public class CodegenServiceImplTest extends BaseDbUnitTest {
234 } 233 }
235 234
236 @Test 235 @Test
237 - @Disabled // TODO @芋艿:这个单测会随机性失败,需要定位下;  
238 public void testSyncCodegenFromDB() { 236 public void testSyncCodegenFromDB() {
239 // mock 数据(CodegenTableDO) 237 // mock 数据(CodegenTableDO)
240 CodegenTableDO table = randomPojo(CodegenTableDO.class, o -> o.setTableName("t_yunai") 238 CodegenTableDO table = randomPojo(CodegenTableDO.class, o -> o.setTableName("t_yunai")
241 .setDataSourceConfigId(1L).setScene(CodegenSceneEnum.ADMIN.getScene())); 239 .setDataSourceConfigId(1L).setScene(CodegenSceneEnum.ADMIN.getScene()));
242 codegenTableMapper.insert(table); 240 codegenTableMapper.insert(table);
243 CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId()) 241 CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
244 - .setColumnName("id")); 242 + .setColumnName("id").setPrimaryKey(true).setOrdinalPosition(0));
245 codegenColumnMapper.insert(column01); 243 codegenColumnMapper.insert(column01);
246 CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId()) 244 CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
247 - .setColumnName("name")); 245 + .setColumnName("name").setOrdinalPosition(1));
248 codegenColumnMapper.insert(column02); 246 codegenColumnMapper.insert(column02);
249 // 准备参数 247 // 准备参数
250 Long tableId = table.getId(); 248 Long tableId = table.getId();
@@ -263,7 +261,7 @@ public class CodegenServiceImplTest extends BaseDbUnitTest { @@ -263,7 +261,7 @@ public class CodegenServiceImplTest extends BaseDbUnitTest {
263 when(databaseTableService.getTable(eq(1L), eq("t_yunai"))) 261 when(databaseTableService.getTable(eq(1L), eq("t_yunai")))
264 .thenReturn(tableInfo); 262 .thenReturn(tableInfo);
265 // mock 方法(CodegenTableDO) 263 // mock 方法(CodegenTableDO)
266 - List<CodegenColumnDO> newColumns = randomPojoList(CodegenColumnDO.class); 264 + List<CodegenColumnDO> newColumns = randomPojoList(CodegenColumnDO.class, 2);
267 when(codegenBuilder.buildColumns(eq(table.getId()), argThat(tableFields -> { 265 when(codegenBuilder.buildColumns(eq(table.getId()), argThat(tableFields -> {
268 assertEquals(2, tableFields.size()); 266 assertEquals(2, tableFields.size());
269 assertSame(tableInfo.getFields(), tableFields); 267 assertSame(tableInfo.getFields(), tableFields);
@@ -457,9 +455,11 @@ public class CodegenServiceImplTest extends BaseDbUnitTest { @@ -457,9 +455,11 @@ public class CodegenServiceImplTest extends BaseDbUnitTest {
457 .setTemplateType(CodegenTemplateTypeEnum.ONE.getType())); 455 .setTemplateType(CodegenTemplateTypeEnum.ONE.getType()));
458 codegenTableMapper.insert(table); 456 codegenTableMapper.insert(table);
459 // mock 数据(CodegenColumnDO) 457 // mock 数据(CodegenColumnDO)
460 - CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())); 458 + CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
  459 + .setOrdinalPosition(1));
461 codegenColumnMapper.insert(column01); 460 codegenColumnMapper.insert(column01);
462 - CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())); 461 + CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
  462 + .setOrdinalPosition(2));
463 codegenColumnMapper.insert(column02); 463 codegenColumnMapper.insert(column02);
464 // mock 执行生成 464 // mock 执行生成
465 Map<String, String> codes = MapUtil.of(randomString(), randomString()); 465 Map<String, String> codes = MapUtil.of(randomString(), randomString());
@@ -486,9 +486,11 @@ public class CodegenServiceImplTest extends BaseDbUnitTest { @@ -486,9 +486,11 @@ public class CodegenServiceImplTest extends BaseDbUnitTest {
486 .setTemplateType(CodegenTemplateTypeEnum.MASTER_NORMAL.getType())); 486 .setTemplateType(CodegenTemplateTypeEnum.MASTER_NORMAL.getType()));
487 codegenTableMapper.insert(table); 487 codegenTableMapper.insert(table);
488 // mock 数据(CodegenColumnDO) 488 // mock 数据(CodegenColumnDO)
489 - CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())); 489 + CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
  490 + .setOrdinalPosition(1));
490 codegenColumnMapper.insert(column01); 491 codegenColumnMapper.insert(column01);
491 - CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())); 492 + CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
  493 + .setOrdinalPosition(2));
492 codegenColumnMapper.insert(column02); 494 codegenColumnMapper.insert(column02);
493 // mock 数据(sub CodegenTableDO) 495 // mock 数据(sub CodegenTableDO)
494 CodegenTableDO subTable = randomPojo(CodegenTableDO.class, 496 CodegenTableDO subTable = randomPojo(CodegenTableDO.class,