DatabaseMetaData 获取 Oracle用户表时,过滤表

Interface DatabaseMetaData


package org.springframework.roo.addon.dbre.model;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import org.springframework.roo.addon.dbre.model.dialect.Dialect;
import org.springframework.roo.model.JavaPackage;
import org.springframework.roo.support.util.Assert;
import org.springframework.roo.support.util.StringUtils;

/**
 * Creates a {@link Database database} model from a live database using JDBC.
 * 
 * @author Alan Stewart
 * @since 1.1
 */
public class DatabaseIntrospector {
	private Connection connection;
	private DatabaseMetaData databaseMetaData;
	private String catalogName;
	private Schema schema;
	private JavaPackage destinationPackage;
	private boolean view;
	private Set<String> includeTables = null;
	private Set<String> excludeTables = null;
	private String tableName;
	private String columnName;

	public DatabaseIntrospector(Connection connection, Schema schema, JavaPackage destinationPackage, boolean view, Set<String> includeTables, Set<String> excludeTables) throws SQLException {
		this(connection);
		catalogName = this.connection.getCatalog();
		databaseMetaData = this.connection.getMetaData();
		Assert.notNull(databaseMetaData, "Database metadata is null");
		this.schema = schema;
		this.destinationPackage = destinationPackage;
		this.view = view;
		this.includeTables = includeTables;
		this.excludeTables = excludeTables;
	}

	public DatabaseIntrospector(Connection connection) throws SQLException {
		Assert.notNull(connection, "Connection must not be null");
		this.connection = connection;
	}

	public Connection getConnection() {
		return connection;
	}

	public String getCatalogName() {
		return catalogName;
	}

	public void setCatalogName(String catalogName) {
		this.catalogName = catalogName;
	}

	public Schema getSchema() {
		return schema;
	}

	public String getSchemaName() {
		return schema != null ? schema.getName() : null;
	}

	public void setSchema(Schema schema) {
		this.schema = schema;
	}

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public String getColumnName() {
		return columnName;
	}

	public void setColumnName(String columnName) {
		this.columnName = columnName;
	}

	public Set<Schema> getSchemas() throws SQLException {
		Set<Schema> schemas = new LinkedHashSet<Schema>();

		ResultSet rs = databaseMetaData.getSchemas();
		try {
			while (rs.next()) {
				schemas.add(new Schema(rs.getString("TABLE_SCHEM")));
			}
		} finally {
			rs.close();
		}

		return schemas;
	}

	public Database createDatabase() throws SQLException {
		String name = StringUtils.hasText(schema.getName()) ? schema.getName() : catalogName;
		return new Database(name, getTables(), destinationPackage);
	}

	private Set<Table> getTables() throws SQLException {
		Set<Table> tables = new LinkedHashSet<Table>();

		String[] types = view ? new String[] { TableType.TABLE.name(), TableType.VIEW.name() } : new String[] { TableType.TABLE.name() };
		ResultSet rs = databaseMetaData.getTables(getCatalog(), getSchemaPattern(), getTableNamePattern(), types);
		try {
			while (rs.next()) {
				tableName = rs.getString("TABLE_NAME");
				catalogName = rs.getString("TABLE_CAT");
				schema = new Schema(rs.getString("TABLE_SCHEM"));

				// Check for certain tables such as Oracle recycle bin tables, and ignore
				if (ignoreTables()) {
					continue;
				}

				if (hasIncludedTable(tableName) && !hasExcludedTable(tableName)) {
					Table table = new Table();
					table.setName(tableName);
					table.setCatalog(catalogName);
					table.setSchema(schema);
					table.setDescription(rs.getString("REMARKS"));

					readColumns(table);
					readForeignKeys(table, false);
					readForeignKeys(table, true);
					readIndices(table);

					for (String columnName : readPrimaryKeyNames()) {
						Column column = table.findColumn(columnName);
						if (column != null) {
							column.setPrimaryKey(true);
						}
					}

					tables.add(table);
				}
			}
		} finally {
			rs.close();
		}

		return tables;
	}

        //这里就是过滤收回站的表
	private boolean ignoreTables() {
		boolean ignore = false;
		try {
			if ("Oracle".equalsIgnoreCase(databaseMetaData.getDatabaseProductName()) && tableName.startsWith("BIN$")) {
				ignore = true;
			}
		} catch (SQLException ignored) {}
		return ignore;
	}

	private void readColumns(Table table) throws SQLException {
		ResultSet rs = databaseMetaData.getColumns(catalogName, getSchemaName(), tableName, getColumnNamePattern());
		try {
			while (rs.next()) {
				Column column = new Column(rs.getString("COLUMN_NAME"), rs.getInt("DATA_TYPE"), rs.getString("TYPE_NAME"), rs.getInt("COLUMN_SIZE"), rs.getInt("DECIMAL_DIGITS"));
				column.setDescription(rs.getString("REMARKS"));
				column.setDefaultValue(rs.getString("COLUMN_DEF"));
				column.setRequired("NO".equalsIgnoreCase(rs.getString("IS_NULLABLE")));

				table.addColumn(column);
			}
		} finally {
			rs.close();
		}
	}

	private void readForeignKeys(Table table, boolean exported) throws SQLException {
		Map<String, ForeignKey> foreignKeys = new LinkedHashMap<String, ForeignKey>();

		ResultSet rs;
		if (exported) {
			rs = databaseMetaData.getExportedKeys(catalogName, getSchemaName(), tableName);
		} else {
			rs = databaseMetaData.getImportedKeys(catalogName, getSchemaName(), tableName);
		}

		try {
			while (rs.next()) {
				String name = rs.getString("FK_NAME");
				String foreignTableName = rs.getString(exported ? "FKTABLE_NAME" : "PKTABLE_NAME");
				String key = name + "_" + foreignTableName;

				if (!hasExcludedTable(foreignTableName)) {
					ForeignKey foreignKey = new ForeignKey(name, foreignTableName);
					foreignKey.setOnUpdate(getCascadeAction(rs.getShort("UPDATE_RULE")));
					foreignKey.setOnDelete(getCascadeAction(rs.getShort("DELETE_RULE")));
					foreignKey.setExported(exported);

					String localColumnName = rs.getString(exported ? "PKCOLUMN_NAME" : "FKCOLUMN_NAME");
					String foreignColumnName = rs.getString(exported ? "FKCOLUMN_NAME" : "PKCOLUMN_NAME");
					Reference reference = new Reference(localColumnName, foreignColumnName);

					if (foreignKeys.containsKey(key)) {
						foreignKeys.get(key).addReference(reference);
					} else {
						foreignKey.addReference(reference);
						foreignKeys.put(key, foreignKey);
					}
				}
			}
		} finally {
			rs.close();
		}

		for (ForeignKey foreignKey : foreignKeys.values()) {
			if (exported) {
				table.addExportedKey(foreignKey);
			} else {
				table.addImportedKey(foreignKey);
			}
		}
	}

	private CascadeAction getCascadeAction(Short actionValue) {
		CascadeAction cascadeAction;
		switch (actionValue.intValue()) {
			case DatabaseMetaData.importedKeyCascade:
				cascadeAction = CascadeAction.CASCADE;
				break;
			case DatabaseMetaData.importedKeySetNull:
				cascadeAction = CascadeAction.SET_NULL;
				break;
			case DatabaseMetaData.importedKeySetDefault:
				cascadeAction = CascadeAction.SET_DEFAULT;
				break;
			case DatabaseMetaData.importedKeyRestrict:
				cascadeAction = CascadeAction.RESTRICT;
				break;
			case DatabaseMetaData.importedKeyNoAction:
				cascadeAction = CascadeAction.NONE;
				break;
			default:
				cascadeAction = CascadeAction.NONE;
		}
		return cascadeAction;
	}

	private boolean hasIncludedTable(String tableName) {
		if (includeTables == null || includeTables.isEmpty()) {
			return true;
		}
		return hasTable(includeTables, tableName);
	}

	private boolean hasExcludedTable(String tableName) {
		if (excludeTables == null || excludeTables.isEmpty()) {
			return false;
		}
		return hasTable(excludeTables, tableName);
	}

	private boolean hasTable(Set<String> tables, String tableName) {
		for (String table : tables) {
			String regex = table.replaceAll("\\*", ".*").replaceAll("\\?", ".?");
			Pattern pattern = Pattern.compile(regex);
			if (pattern.matcher(tableName).matches()) {
				return true;
			}
		}
		return false;
	}

	private void readIndices(Table table) throws SQLException {
		Set<Index> indices = new LinkedHashSet<Index>();

		ResultSet rs;
		try {
			// Catching SQLException here due to Oracle throwing exception when attempting to retrieve indices for deleted tables that exist in Oracle's recycle bin
			rs = databaseMetaData.getIndexInfo(catalogName, getSchemaName(), tableName, false, false);
		} catch (SQLException e) {
			return;
		}

		if (rs != null) {
			try {
				while (rs.next()) {
					Short type = rs.getShort("TYPE");
					if (type == DatabaseMetaData.tableIndexStatistic) {
						continue;
					}

					String indexName = rs.getString("INDEX_NAME");
					Index index = findIndex(indexName, indices);
					if (index == null) {
						index = new Index(indexName);
					} else {
						indices.remove(index);
					}
					index.setUnique(!rs.getBoolean("NON_UNIQUE"));

					IndexColumn indexColumn = new IndexColumn(rs.getString("COLUMN_NAME"));
					index.addColumn(indexColumn);

					indices.add(index);
				}
			} finally {
				rs.close();
			}
		}

		for (Index index : indices) {
			table.addIndex(index);
		}
	}

	private Index findIndex(String name, Set<Index> indices) {
		for (Index index : indices) {
			if (index.getName().equalsIgnoreCase(name)) {
				return index;
			}
		}
		return null;
	}

	private Set<String> readPrimaryKeyNames() throws SQLException {
		Set<String> columnNames = new LinkedHashSet<String>();

		ResultSet rs = databaseMetaData.getPrimaryKeys(catalogName, getSchemaName(), tableName);
		try {
			while (rs.next()) {
				columnNames.add(rs.getString("COLUMN_NAME"));
			}
		} finally {
			rs.close();
		}

		return columnNames;
	}

	private String getCatalog() throws SQLException {
		if (databaseMetaData.storesLowerCaseIdentifiers()) {
			return StringUtils.toLowerCase(catalogName);
		} else if (databaseMetaData.storesUpperCaseIdentifiers()) {
			return StringUtils.toUpperCase(catalogName);
		} else {
			return catalogName;
		}
	}

	private String getSchemaPattern() throws SQLException {
		if (databaseMetaData.storesLowerCaseIdentifiers()) {
			return StringUtils.toLowerCase(getSchemaName());
		} else if (databaseMetaData.storesUpperCaseIdentifiers()) {
			return StringUtils.toUpperCase(getSchemaName());
		} else {
			return getSchemaName();
		}
	}

	private String getTableNamePattern() throws SQLException {
		if (databaseMetaData.storesLowerCaseIdentifiers()) {
			return StringUtils.toLowerCase(tableName);
		} else if (databaseMetaData.storesUpperCaseIdentifiers()) {
			return StringUtils.toUpperCase(tableName);
		} else {
			return tableName;
		}
	}

	private String getColumnNamePattern() throws SQLException {
		if (databaseMetaData.storesLowerCaseIdentifiers()) {
			return StringUtils.toLowerCase(columnName);
		} else if (databaseMetaData.storesUpperCaseIdentifiers()) {
			return StringUtils.toUpperCase(columnName);
		} else {
			return columnName;
		}
	}

	@SuppressWarnings("unused") private Dialect getDialect() {
		try {
			String productName = databaseMetaData.getDatabaseProductName();
			return (Dialect) Class.forName("org.springframework.roo.addon.dbre.model.dialect." + productName + "Dialect").newInstance();
		} catch (Exception e) {
			return null;
		}
	}
}



转载于:https://my.oschina.net/i33/blog/170439

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值