Mybatis-plus代码生成器通过Oracle,只生成文件而不能生成字节码的原因探究

源码分析

Mybatis-plus逆向工程生成源码的主要流程是在AutoGenerator调用execute()方法时,会根据你设置的DataSourceConfig里的

DbType属性,判断你的数据库类型,然后从你的数据库查询出来相应的数据表名,而后将信息存入到TableInfo里,而后进行逆向生

成,进行逆向生成的过程中。

第一步解析配置:

/**
 * 生成代码
 */
public void execute() {
    logger.debug("==========================准备生成文件...==========================");
    // 初始化配置
    if (null == config) {
       //这里会生成配置,非常重要,也是唯一受可以受我们影响的,也是最容易出问题的,我就是在这里出了错。
        config = new ConfigBuilder(packageInfo, dataSource, strategy, template, globalConfig);
        if (null != injectionConfig) {
            injectionConfig.setConfig(config);
        }
    }
    if (null == templateEngine) {
        // 为了兼容之前逻辑,采用 Velocity 引擎 【 默认 】
        templateEngine = new VelocityTemplateEngine();
    }
    // 模板引擎初始化执行文件输出
    templateEngine.init(this.pretreatmentConfigBuilder(config)).mkdirs().batchOutput().open();
    logger.debug("==========================文件生成完成!!!==========================");
}

第二步:使用new ConfigBuilder(packageInfo, dataSource, strategy, template, globalConfig);去生成config配置信息。

public ConfigBuilder(PackageConfig packageConfig, DataSourceConfig dataSourceConfig, StrategyConfig strategyConfig,
                     TemplateConfig template, GlobalConfig globalConfig) {
    // 全局配置
    if (null == globalConfig) {
        this.globalConfig = new GlobalConfig();
    } else {
        this.globalConfig = globalConfig;
    }
    // 模板配置
    if (null == template) {
        this.template = new TemplateConfig();
    } else {
        this.template = template;
    }
    // 包配置
    if (null == packageConfig) {
        handlerPackage(this.template, this.globalConfig.getOutputDir(), new PackageConfig());
    } else {
        handlerPackage(this.template, this.globalConfig.getOutputDir(), packageConfig);
    }
    this.dataSourceConfig = dataSourceConfig;
    //这一步,就是解析你配置的dataSourceConfig对象
    handlerDataSource(dataSourceConfig);
    // 策略配置
    if (null == strategyConfig) {
        this.strategyConfig = new StrategyConfig();
    } else {
        this.strategyConfig = strategyConfig;
    }
    //SQLITE 数据库不支持注释获取
    commentSupported = !dataSourceConfig.getDbType().equals(DbType.SQLITE);
    //这里会进行非常重要的功能解析,其中要针对哪些表的操作,就是发生在这里
    handlerStrategy(this.strategyConfig);
}

第三步:执行handlerStrategy(this.strategyConfig);这里会针对你的配置,来对表进行处理

private void handlerStrategy(StrategyConfig config) {
    processTypes(config);
    //这一步就是根据你配置的信息,去获取相关的表及表的column信息
    tableInfoList = getTablesInfo(config);
}

第四步:执行 getTablesInfo(config);

private List getTablesInfo(StrategyConfig config) {
    boolean isInclude = (null != config.getInclude() && config.getInclude().length > 0);
    boolean isExclude = (null != config.getExclude() && config.getExclude().length > 0);
    if (isInclude && isExclude) {
        throw new RuntimeException(" 标签中  只能配置一项!");
    }
    if (config.getNotLikeTable() != null && config.getLikeTable() != null) {
        throw new RuntimeException(" 标签中  只能配置一项!");
    }
    //所有的表信息
    List tableList = new ArrayList<>();

    //需要反向生成或排除的表信息
    List includeTableList = new ArrayList<>();
    List excludeTableList = new ArrayList<>();

    //不存在的表名
    Set notExistTables = new HashSet<>();
     //这里非常重要,这里会判断你要解析的数据库类型,并且生成对数据库的数据表查询语句
    try {
        String tablesSql = dbQuery.tablesSql();
        if (DbType.POSTGRE_SQL == this.dbType) {
            String schema = dataSourceConfig.getSchemaName();
            if (schema == null) {
                //pg 默认 schema=public
                schema = "public";
                dataSourceConfig.setSchemaName(schema);
            }
            tablesSql = String.format(tablesSql, schema);
        } else if (DbType.KINGBASE_ES == this.dbType) {
            String schema = dataSourceConfig.getSchemaName();
            if (schema == null) {
                //kingbase 默认 schema=PUBLIC
                schema = "PUBLIC";
                dataSourceConfig.setSchemaName(schema);
            }
            tablesSql = String.format(tablesSql, schema);
        } else if (DbType.DB2 == this.dbType) {
            String schema = dataSourceConfig.getSchemaName();
            if (schema == null) {
                //db2 默认 schema=current schema
                schema = "current schema";
                dataSourceConfig.setSchemaName(schema);
            }
            tablesSql = String.format(tablesSql, schema);
        }
        //oracle数据库表太多,出现最大游标错误
        else if (DbType.ORACLE == this.dbType) {
            String schema = dataSourceConfig.getSchemaName();
            //oracle 默认 schema=username
            if (schema == null) {
                schema = dataSourceConfig.getUsername().toUpperCase();
                dataSourceConfig.setSchemaName(schema);
            }
           //这里就是生成数据库查询表的语句,我的正是这里出了问题,因为我的数据库用户名和密码,并不是和我数据库的
            scheam相同,所以导致,生成的查询表语句,查不到对应的表,而官方示例的代码里又没有配置scheam的,导致我的
            查不到对应表。而且基本上排查到这一步,就能查询出问题了。
            tablesSql = String.format(tablesSql, schema);
        }
        StringBuilder sql = new StringBuilder(tablesSql);
        if (config.isEnableSqlFilter()) {
            if (config.getLikeTable() != null) {
                sql.append(" AND ").append(dbQuery.tableName()).append(" LIKE '").append(config.getLikeTable().getValue()).append("'");
            } else if (config.getNotLikeTable() != null) {
                sql.append(" AND ").append(dbQuery.tableName()).append(" NOT LIKE '").append(config.getNotLikeTable().getValue()).append("'");
            }
            if (isInclude) {
                sql.append(" AND ").append(dbQuery.tableName()).append(" IN (")
                    .append(Arrays.stream(config.getInclude()).map(tb -> "'" + tb + "'").collect(Collectors.joining(","))).append(")");
            } else if (isExclude) {
                sql.append(" AND ").append(dbQuery.tableName()).append(" NOT IN (")
                    .append(Arrays.stream(config.getExclude()).map(tb -> "'" + tb + "'").collect(Collectors.joining(","))).append(")");
            }
        }
        TableInfo tableInfo;
        try (PreparedStatement preparedStatement = connection.prepareStatement(sql.toString());
             ResultSet results = preparedStatement.executeQuery()) {
            while (results.next()) {
                String tableName = results.getString(dbQuery.tableName());
                if (StringUtils.isNotBlank(tableName)) {
                    tableInfo = new TableInfo();
                    tableInfo.setName(tableName);

                    if (commentSupported) {
                        String tableComment = results.getString(dbQuery.tableComment());
                        if (config.isSkipView() && "VIEW".equals(tableComment)) {
                            // 跳过视图
                            continue;
                        }
                        tableInfo.setComment(tableComment);
                    }

                    if (isInclude) {
                        for (String includeTable : config.getInclude()) {
                            // 忽略大小写等于 或 正则 true
                            if (tableNameMatches(includeTable, tableName)) {
                                includeTableList.add(tableInfo);
                            } else {
                                //过滤正则表名
                                if (!REGX.matcher(includeTable).find()) {
                                    notExistTables.add(includeTable);
                                }
                            }
                        }
                    } else if (isExclude) {
                        for (String excludeTable : config.getExclude()) {
                            // 忽略大小写等于 或 正则 true
                            if (tableNameMatches(excludeTable, tableName)) {
                                excludeTableList.add(tableInfo);
                            } else {
                                //过滤正则表名
                                if (!REGX.matcher(excludeTable).find()) {
                                    notExistTables.add(excludeTable);
                                }
                            }
                        }
                    }
                    tableList.add(tableInfo);
                } else {
                    System.err.println("当前数据库为空!!!");
                }
            }
        }
        // 将已经存在的表移除,获取配置中数据库不存在的表
        for (TableInfo tabInfo : tableList) {
            notExistTables.remove(tabInfo.getName());
        }
        if (notExistTables.size() > 0) {
            System.err.println("表 " + notExistTables + " 在数据库中不存在!!!");
        }

        // 需要反向生成的表信息
        if (isExclude) {
            tableList.removeAll(excludeTableList);
            includeTableList = tableList;
        }
        if (!isInclude && !isExclude) {
            includeTableList = tableList;
        }
        // 性能优化,只处理需执行表字段 github issues/219
        includeTableList.forEach(ti -> convertTableFields(ti, config));
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return processTable(includeTableList, config.getNaming(), config);
}

你可能感兴趣的:(Mybaties-plugs)