@Override
    @Transactional(rollbackFor = Exception.class)
    public void syncCodegenFromDB(Long tableId) {
        // 校验是否已经存在
        CodegenTableDO table = codegenTableMapper.selectById(tableId);
        if (table == null) {
            throw exception(CODEGEN_TABLE_NOT_EXISTS);
        }
        // 从数据库中，获得数据库表结构
        TableInfo tableInfo = databaseTableService.getTable(table.getDataSourceConfigId(), table.getTableName());
        // 执行同步
        syncCodegen0(tableId, tableInfo);
    }
@Test
    @Disabled // TODO @芋艿：这个单测会随机性失败，需要定位下；
    public void testSyncCodegenFromDB() {
        // mock 数据（CodegenTableDO）
        CodegenTableDO table = randomPojo(CodegenTableDO.class, o -> o.setTableName("t_yunai")
                .setDataSourceConfigId(1L).setScene(CodegenSceneEnum.ADMIN.getScene()));
        codegenTableMapper.insert(table);
        CodegenColumnDO column01 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
                .setColumnName("id"));
        codegenColumnMapper.insert(column01);
        CodegenColumnDO column02 = randomPojo(CodegenColumnDO.class, o -> o.setTableId(table.getId())
                .setColumnName("name"));
        codegenColumnMapper.insert(column02);
        // 准备参数
        Long tableId = table.getId();
        // mock 方法（TableInfo）
        TableInfo tableInfo = mock(TableInfo.class);
        when(databaseTableService.getTable(eq(1L), eq("t_yunai")))
                .thenReturn(tableInfo);
        when(tableInfo.getComment()).thenReturn("芋艿");
        // mock 方法（TableInfo fields）
        TableField field01 = mock(TableField.class);
        when(field01.getComment()).thenReturn("主键");
        TableField field03 = mock(TableField.class);
        when(field03.getComment()).thenReturn("分类");
        List<TableField> fields = Arrays.asList(field01, field03);
        when(tableInfo.getFields()).thenReturn(fields);
        when(databaseTableService.getTable(eq(1L), eq("t_yunai")))
                .thenReturn(tableInfo);
        // mock 方法（CodegenTableDO）
        List<CodegenColumnDO> newColumns = randomPojoList(CodegenColumnDO.class);
        when(codegenBuilder.buildColumns(eq(table.getId()), argThat(tableFields -> {
            assertEquals(2, tableFields.size());
            assertSame(tableInfo.getFields(), tableFields);
            return true;
        }))).thenReturn(newColumns);

        // 调用
        codegenService.syncCodegenFromDB(tableId);
        // 断言
        List<CodegenColumnDO> dbColumns = codegenColumnMapper.selectList();
        assertEquals(newColumns.size(), dbColumns.size());
        assertPojoEquals(newColumns.get(0), dbColumns.get(0));
        assertPojoEquals(newColumns.get(1), dbColumns.get(1));
    }