001package cn.mybatis.mp.generator.database.meta; 002 003import cn.mybatis.mp.generator.config.GeneratorConfig; 004import lombok.extern.slf4j.Slf4j; 005import org.apache.ibatis.type.JdbcType; 006 007import java.sql.Connection; 008import java.sql.DatabaseMetaData; 009import java.sql.ResultSet; 010import java.sql.SQLException; 011import java.util.ArrayList; 012import java.util.HashSet; 013import java.util.List; 014import java.util.Set; 015import java.util.stream.Collectors; 016 017@Slf4j 018public class TableMetaDataQuery { 019 020 protected final DatabaseMetaData metaData; 021 022 protected final GeneratorConfig generatorConfig; 023 024 protected final String connDatabaseName; 025 026 public TableMetaDataQuery(GeneratorConfig generatorConfig, Connection connection) throws SQLException { 027 this.metaData = connection.getMetaData(); 028 this.generatorConfig = generatorConfig; 029 this.connDatabaseName = connection.getCatalog(); 030 } 031 032 public List<TableInfo> getTableInfoList(boolean includeTable, boolean includeView) { 033 Set<String> types = new HashSet<>(); 034 if (includeTable) { 035 types.add("TABLE"); 036 } 037 if (includeView) { 038 types.add("VIEW"); 039 } 040 041 List<TableInfo> tables = new ArrayList<>(); 042 043 String databaseName = generatorConfig.getDataBaseConfig().getDatabaseName(); 044 if (databaseName == null) { 045 databaseName = this.connDatabaseName; 046 } 047 048 try (ResultSet resultSet = metaData.getTables(databaseName, generatorConfig.getDataBaseConfig().getSchema(), null, types.toArray(new String[2]))) { 049 TableInfo tableInfo; 050 while (resultSet.next()) { 051 String TABLE_NAME = resultSet.getString("TABLE_NAME"); 052 String tableName = TABLE_NAME; 053 if (tableName.toUpperCase().equals(tableName)) { 054 tableName = tableName.toLowerCase(); 055 } 056 tableInfo = new TableInfo(); 057 tableInfo.setName(tableName); 058 tableInfo.setRemarks(resultSet.getString("REMARKS")); 059 tableInfo.setTableType(resultSet.getString("TABLE_TYPE")); 060 tableInfo.setSchema(resultSet.getString("TABLE_SCHEM")); 061 tableInfo.setCatalog(resultSet.getString("TABLE_CAT")); 062 063 tableInfo.setColumnInfoList(getColumnInfo(tableInfo, TABLE_NAME)); 064 List<ColumnInfo> idColumnInfoList = tableInfo.getColumnInfoList().stream().filter(item -> item.isPrimaryKey()).collect(Collectors.toList()); 065 if (!idColumnInfoList.isEmpty()) { 066 tableInfo.setIdColumnInfo(idColumnInfoList.get(0)); 067 } 068 tables.add(tableInfo); 069 } 070 } catch (SQLException e) { 071 throw new RuntimeException("读取数据库表信息出现错误", e); 072 } 073 return tables; 074 } 075 076 private List<ColumnInfo> getColumnInfo(TableInfo tableInfo, String tableName) { 077 Set<String> primaryKeys = new HashSet<>(); 078 if (!tableInfo.isView()) { 079 try (ResultSet primaryKeysResultSet = metaData.getPrimaryKeys(tableInfo.getCatalog(), tableInfo.getSchema(), tableName)) { 080 while (primaryKeysResultSet.next()) { 081 String columnName = primaryKeysResultSet.getString("COLUMN_NAME"); 082 if (columnName.toUpperCase().equals(columnName)) { 083 columnName = columnName.toLowerCase(); 084 } 085 primaryKeys.add(columnName); 086 } 087 } catch (SQLException e) { 088 throw new RuntimeException("读取表主键信息:" + tableInfo.getName() + "错误:", e); 089 } 090 } 091 092 if (primaryKeys.size() > 1) { 093 log.warn("当前表:{},存在多主键情况!", tableInfo.getName()); 094 } 095 096 List<ColumnInfo> columnsInfoList = new ArrayList<>(); 097 try (ResultSet resultSet = metaData.getColumns(tableInfo.getCatalog(), tableInfo.getSchema(), tableName, "%")) { 098 while (resultSet.next()) { 099 String columnName = resultSet.getString("COLUMN_NAME"); 100 if (columnName.toUpperCase().equals(columnName)) { 101 columnName = columnName.toLowerCase(); 102 } 103 104 ColumnInfo columnInfo = new ColumnInfo(); 105 columnInfo.setTableInfo(tableInfo); 106 columnInfo.setName(columnName); 107 columnInfo.setPrimaryKey(primaryKeys.contains(columnInfo.getName())); 108 109 columnInfo.setTypeName(resultSet.getString("TYPE_NAME")); 110 columnInfo.setJdbcType(JdbcType.forCode(resultSet.getInt("DATA_TYPE"))); 111 columnInfo.setLength(resultSet.getInt("COLUMN_SIZE")); 112 columnInfo.setScale(resultSet.getInt("DECIMAL_DIGITS")); 113 columnInfo.setRemarks(resultSet.getString("REMARKS")); 114 columnInfo.setDefaultValue(resultSet.getString("COLUMN_DEF")); 115 columnInfo.setNullable(resultSet.getInt("NULLABLE") == DatabaseMetaData.columnNullable); 116 117 columnInfo.setVersion(columnName.equals(generatorConfig.getColumnConfig().getVersionColumn())); 118 columnInfo.setTenantId(columnName.equals(generatorConfig.getColumnConfig().getTenantIdColumn())); 119 try { 120 columnInfo.setAutoIncrement("YES".equals(resultSet.getString("IS_AUTOINCREMENT"))); 121 } catch (SQLException e) { 122 log.error("获取自增信息异常:", e); 123 } 124 columnsInfoList.add(columnInfo); 125 } 126 return columnsInfoList; 127 } catch (SQLException e) { 128 throw new RuntimeException("读取表字段信息:" + tableInfo.getName() + "错误:", e); 129 } 130 } 131}