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 ListgetTablesInfo(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); }