All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sagacity.quickvo.utils.DBHelper Maven / Gradle / Ivy

There is a newer version: 1.0.4
Show newest version
/**
 * 
 */
package org.sagacity.quickvo.utils;

import static java.lang.System.err;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import org.sagacity.quickvo.Constants;
import org.sagacity.quickvo.model.DataSourceModel;
import org.sagacity.quickvo.model.IndexModel;
import org.sagacity.quickvo.model.TableColumnMeta;
import org.sagacity.quickvo.model.TableConstractModel;
import org.sagacity.quickvo.model.TableMeta;
import org.sagacity.quickvo.utils.DBUtil.DBType;
import org.sagacity.quickvo.utils.callback.PreparedStatementResultHandler;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * @project sagacity-quickvo
 * @description quickvo数据库解析
 * @author zhongxuchen
 * @version v1.0,Date:2010-7-12
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class DBHelper {
	/**
	 * 定义全局日志
	 */
	private static Logger logger = LoggerUtil.getLogger();

	/**
	 * 数据库连接
	 */
	private static Connection conn;

	private static DataSourceModel dbConfig = null;

	private static HashMap dbMaps = new HashMap();

	/**
	 * @todo 加载数据库配置
	 * @param datasouceElts
	 * @throws Exception
	 */
	public static void loadDatasource(NodeList datasouceElts) throws Exception {
		if (datasouceElts == null || datasouceElts.getLength() == 0) {
			logger.info("没有配置相应的数据库");
			throw new Exception("没有配置相应的数据库");
		}
		Element datasouceElt;
		for (int m = 0; m < datasouceElts.getLength(); m++) {
			datasouceElt = (Element) datasouceElts.item(m);
			DataSourceModel dbModel = new DataSourceModel();
			String name = null;
			if (datasouceElt.hasAttribute("name")) {
				name = datasouceElt.getAttribute("name");
			}
			if (datasouceElt.hasAttribute("catalog")) {
				dbModel.setCatalog(Constants.replaceConstants(datasouceElt.getAttribute("catalog")));
			}
			if (datasouceElt.hasAttribute("schema")) {
				dbModel.setSchema(Constants.replaceConstants(datasouceElt.getAttribute("schema")));
			}
			dbModel.setUrl(Constants.replaceConstants(datasouceElt.getAttribute("url")));
			dbModel.setDriver(Constants.replaceConstants(datasouceElt.getAttribute("driver")));
			dbModel.setUsername(Constants.replaceConstants(datasouceElt.getAttribute("username")));
			dbModel.setPassword(Constants.replaceConstants(datasouceElt.getAttribute("password")));
			dbMaps.put(StringUtil.isBlank(name) ? ("" + m) : name, dbModel);
		}
	}

	/**
	 * @todo 获取数据库连接
	 * @param dbName
	 * @return
	 * @throws Exception
	 */
	public static boolean getConnection(String dbName) throws Exception {
		dbConfig = dbMaps.get(StringUtil.isBlank(dbName) ? "0" : dbName);
		if (dbConfig == null && dbMaps.size() == 1 && StringUtil.isBlank(dbName)) {
			dbConfig = dbMaps.values().iterator().next();
		}
		if (dbConfig != null) {
			logger.info("开始连接数据库:" + dbName + ",url:" + dbConfig.getUrl());
			try {
				Class.forName(dbConfig.getDriver());
				conn = DriverManager.getConnection(dbConfig.getUrl(), dbConfig.getUsername(), dbConfig.getPassword());
				return true;
			} catch (ClassNotFoundException cnfe) {
				cnfe.printStackTrace();
				logger.info("数据库驱动未能加载,请在/libs 目录下放入正确的数据库驱动jar包,或请再参照文档了解quickvo-maven插件的配置!");
				throw cnfe;
			} catch (SQLException se) {
				logger.info("获取数据库连接失败!");
				throw se;
			}
		} else {
			logger.info("数据库名称:" + dbName + "不在dataSource定义的名单中,请检查 的一致性");
		}
		return false;
	}

	/**
	 * @todo 关闭数据库并销毁
	 */
	public static void close() {
		try {
			if (conn != null) {
				conn.close();
				conn = null;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * @todo 获取符合条件的表和视图
	 * @param includes
	 * @param excludes
	 * @return
	 * @throws Exception
	 */
	public static List getTableAndView(final String[] includes, final String[] excludes) throws Exception {
		int dbType = DBUtil.getDbType(conn);
		String schema = dbConfig.getSchema();
		String catalog = dbConfig.getCatalog();
		logger.info("提取数据库:schema=[" + schema + "]和 catalog=[" + catalog + "]");
		String[] types = new String[] { "TABLE", "VIEW" };
		PreparedStatement pst = null;
		ResultSet rs = null;
		// 数据库表注释,默认为remarks,不同数据库其名称不一样
		String commentName = "REMARKS";
		boolean isPolardb = dbConfig.getUrl().toLowerCase().contains("polardb");
		boolean skipGetTables = false;
		// oracle数据库
		if ((dbType == DBType.ORACLE || dbType == DBType.ORACLE11) && !isPolardb) {
			try {
				pst = conn.prepareStatement("select * from user_tab_comments");
				rs = pst.executeQuery();
				commentName = "COMMENTS";
				skipGetTables = true;
			} catch (Exception e) {
				logger.info("表:user_tab_comments 不存在,如当前非oracle数据库(如:polardb等),此错误请忽略!");
			}
		} // mysql数据库
		if ((dbType == DBType.MYSQL || dbType == DBType.MYSQL57) && !isPolardb) {
			try {
				StringBuilder queryStr = new StringBuilder("SELECT TABLE_NAME,TABLE_SCHEMA,TABLE_TYPE,TABLE_COMMENT ");
				queryStr.append(" FROM INFORMATION_SCHEMA.TABLES where 1=1 ");
				if (schema != null) {
					queryStr.append(" and TABLE_SCHEMA='").append(schema).append("'");
				} else if (catalog != null) {
					queryStr.append(" and TABLE_SCHEMA='").append(catalog).append("'");
				}
				if (types != null) {
					queryStr.append(" and (");
					for (int i = 0; i < types.length; i++) {
						if (i > 0) {
							queryStr.append(" or ");
						}
						queryStr.append(" TABLE_TYPE like '%").append(types[i]).append("'");
					}
					queryStr.append(")");
				}
				pst = conn.prepareStatement(queryStr.toString());
				rs = pst.executeQuery();
				commentName = "TABLE_COMMENT";
				skipGetTables = true;
			} catch (Exception e) {
				logger.info("表:INFORMATION_SCHEMA.TABLES 不存在,如当前非mysql数据库(如:polardb、dorisdb等),此错误请忽略!");
			}
		}
		if (!skipGetTables) {
			// 获取当前数据库的全部表名信息
			rs = conn.getMetaData().getTables(catalog, schema, null, types);
		}
		return (List) DBUtil.preparedStatementProcess(commentName, pst, rs, new PreparedStatementResultHandler() {
			public void execute(Object obj, PreparedStatement pst, ResultSet rs) throws Exception {
				List tables = new ArrayList();
				String tableName;
				// 是否包含标识,通过正则表达是判断是否是需要获取的表
				boolean is_include = false;
				String type;
				while (rs.next()) {
					is_include = false;
					tableName = rs.getString("TABLE_NAME");
					if (includes != null && includes.length > 0) {
						for (int i = 0; i < includes.length; i++) {
							if (StringUtil.matches(tableName, includes[i])) {
								is_include = true;
								break;
							}
						}
					} else {
						is_include = true;
					}
					if (excludes != null && excludes.length > 0) {
						for (int j = 0; j < excludes.length; j++) {
							if (StringUtil.matches(tableName, excludes[j])) {
								is_include = false;
								break;
							}
						}
					}
					if (is_include) {
						TableMeta tableMeta = new TableMeta();
						tableMeta.setTableName(tableName);
						tableMeta.setSchema(dbConfig.getSchema());
						// tableMeta.setSchema(rs.getString("TABLE_SCHEM"));
						// tableMeta.setSchema(rs.getString("TABLE_CAT"));
						type = rs.getString("TABLE_TYPE").toLowerCase();
						if (type.contains("view")) {
							tableMeta.setTableType("VIEW");
						} else {
							tableMeta.setTableType("TABLE");
						}
						tableMeta.setTableRemark(StringUtil.clearMistyChars(rs.getString(obj.toString()), " "));
						tables.add(tableMeta);
					}
				}
				this.setResult(tables);
			}
		});
	}

	/**
	 * @todo 获取表名的注释
	 * @param tableName
	 * @return
	 * @throws Exception
	 */
	public static String getTableRemark(String tableName) throws Exception {
		final int dbType = DBUtil.getDbType(conn);
		PreparedStatement pst = null;
		ResultSet rs;
		// sqlserver
		String tableComment = null;
		if (dbType == DBType.SQLSERVER) {
			StringBuilder queryStr = new StringBuilder();
			queryStr.append("select cast(isnull(f.value,'') as varchar(1000)) COMMENTS");
			queryStr.append(" from syscolumns a");
			queryStr.append(" inner join sysobjects d on a.id=d.id and d.xtype='U' and d.name<>'dtproperties'");
			queryStr.append(" left join sys.extended_properties f on d.id=f.major_id and f.minor_id=0");
			queryStr.append(" where a.colorder=1 and d.name=?");
			pst = conn.prepareStatement(queryStr.toString());
			pst.setString(1, tableName);
			rs = pst.executeQuery();
			tableComment = (String) DBUtil.preparedStatementProcess(null, pst, rs,
					new PreparedStatementResultHandler() {
						public void execute(Object obj, PreparedStatement pst, ResultSet rs) throws SQLException {
							while (rs.next()) {
								this.setResult(rs.getString("COMMENTS"));
							}
						}
					});
		}
		return tableComment;
	}

	/**
	 * @todo 获取表的字段信息
	 * @param tableName
	 * @param toUpperCase
	 * @return
	 * @throws Exception
	 */
	public static List getTableColumnMeta(final String tableName, boolean toUpperCase) throws Exception {
		final int dbType = DBUtil.getDbType(conn);
		PreparedStatement pst = null;
		ResultSet rs;
		HashMap filedsComments = null;
		boolean isPolardb = dbConfig.getUrl().toLowerCase().contains("polardb");
		// sybase or sqlserver
		if (dbType == DBType.SQLSERVER && !isPolardb) {
			if (dbType == DBType.SQLSERVER) {
				StringBuilder queryStr = new StringBuilder();
				queryStr.append("SELECT a.name COLUMN_NAME,");
				queryStr.append(" cast(isnull(g.[value],'') as varchar(1000)) as COMMENTS");
				queryStr.append(" FROM syscolumns a");
				queryStr.append(" inner join sysobjects d on a.id=d.id ");
				queryStr.append(" and d.xtype='U' and d.name<>'dtproperties'");
				queryStr.append(" left join syscomments e");
				queryStr.append(" on a.cdefault=e.id");
				queryStr.append(" left join sys.extended_properties g");
				queryStr.append(" on a.id=g.major_id AND a.colid = g.minor_id");
				queryStr.append(" where d.name=?");
				queryStr.append(" order by a.id,a.colorder");
				pst = conn.prepareStatement(queryStr.toString());
				pst.setString(1, tableName);
				rs = pst.executeQuery();
				filedsComments = (HashMap) DBUtil.preparedStatementProcess(null, pst, rs,
						new PreparedStatementResultHandler() {
							public void execute(Object obj, PreparedStatement pst, ResultSet rs) throws SQLException {
								HashMap filedHash = new HashMap();
								while (rs.next()) {
									TableColumnMeta colMeta = new TableColumnMeta();
									colMeta.setColName(rs.getString("COLUMN_NAME"));
									colMeta.setColRemark(rs.getString("COMMENTS"));
									filedHash.put(rs.getString("COLUMN_NAME"), colMeta);
								}
								this.setResult(filedHash);
							}
						});
			}
			String queryStr = "{call sp_columns ('" + tableName + "')}";
			pst = conn.prepareCall(queryStr);
			rs = pst.executeQuery();
			final HashMap metaMap = filedsComments;
			return (List) DBUtil.preparedStatementProcess(null, null, rs, new PreparedStatementResultHandler() {

				public void execute(Object obj, PreparedStatement pst, ResultSet rs) throws SQLException {
					List result = new ArrayList();
					String isAutoIncrement;
					String colName;
					while (rs.next()) {
						TableColumnMeta colMeta;
						colName = rs.getString("COLUMN_NAME");
						if (colName == null) {
							colName = rs.getString("column_name");
						}
						if (dbType == DBType.SQLSERVER) {
							if (metaMap == null) {
								colMeta = new TableColumnMeta();
								colMeta.setColName(colName);
								colMeta.setColRemark(rs.getString("REMARKS"));
							} else {
								colMeta = (TableColumnMeta) metaMap.get(colName);
							}
						} else {
							colMeta = new TableColumnMeta();
						}
						if (colMeta != null) {
							colMeta.setColDefault(clearDefaultValue(StringUtil.trim(rs.getString("column_def"))));
							colMeta.setDataType(rs.getInt("data_type"));
							colMeta.setTypeName(rs.getString("type_name"));
							if (rs.getInt("char_octet_length") != 0) {
								colMeta.setLength(rs.getInt("char_octet_length"));
							} else {
								colMeta.setLength(rs.getInt("precision"));
							}
							colMeta.setPrecision(colMeta.getLength());
							// 字段名称
							colMeta.setColName(colName);
							colMeta.setScale(rs.getInt("scale"));
							colMeta.setNumPrecRadix(rs.getInt("radix"));
							try {
								isAutoIncrement = rs.getString("IS_AUTOINCREMENT");
								if (isAutoIncrement != null && (isAutoIncrement.equalsIgnoreCase("true")
										|| isAutoIncrement.equalsIgnoreCase("YES")
										|| isAutoIncrement.equalsIgnoreCase("Y") || isAutoIncrement.equals("1"))) {
									colMeta.setAutoIncrement(true);
								} else {
									colMeta.setAutoIncrement(false);
								}
							} catch (Exception e) {
							}
							if (colMeta.getTypeName().toLowerCase().indexOf("identity") != -1) {
								colMeta.setAutoIncrement(true);
							}
							// 是否可以为空
							if (rs.getInt("nullable") == 1) {
								colMeta.setNullable(true);
							} else {
								colMeta.setNullable(false);
							}
							result.add(colMeta);
						} else {
							err.println("表:" + tableName + " 对应的列:" + colName + "不在当前用户表字段内,请检查schema或catalog配置是否正确!");
							logger.info("表:" + tableName + " 对应的列:" + colName + "不在当前用户表字段内,请检查schema或catalog配置是否正确!");
						}
					}
					this.setResult(result);
				}
			});
		}
		try {
			// oracle 数据库
			if ((dbType == DBType.ORACLE || dbType == DBType.ORACLE11) && !isPolardb) {
				StringBuilder queryStr = new StringBuilder();
				queryStr.append("SELECT t1.*,t2.DATA_DEFAULT FROM (SELECT COLUMN_NAME,COMMENTS");
				queryStr.append("  FROM user_col_comments");
				queryStr.append("  WHERE table_name =?) t1");
				queryStr.append("  LEFT JOIN(SELECT COLUMN_NAME,DATA_DEFAULT");
				queryStr.append("            FROM user_tab_cols");
				queryStr.append("            WHERE table_name =?) t2");
				queryStr.append("  on t1.COLUMN_NAME=t2.COLUMN_NAME");
				pst = conn.prepareStatement(queryStr.toString());
				pst.setString(1, tableName);
				pst.setString(2, tableName);
				rs = pst.executeQuery();
				filedsComments = (HashMap) DBUtil.preparedStatementProcess(null, pst, rs,
						new PreparedStatementResultHandler() {
							public void execute(Object obj, PreparedStatement pst, ResultSet rs) throws SQLException {
								HashMap filedHash = new HashMap();
								while (rs.next()) {
									TableColumnMeta colMeta = new TableColumnMeta();
									colMeta.setColName(rs.getString("COLUMN_NAME"));
									colMeta.setColRemark(StringUtil.clearMistyChars(rs.getString("COMMENTS"), " "));
									colMeta.setColDefault(StringUtil.trim(rs.getString("DATA_DEFAULT")));
									filedHash.put(rs.getString("COLUMN_NAME"), colMeta);
								}
								this.setResult(filedHash);
							}
						});
			}
		} catch (Exception e) {
			logger.info("如果当前数据库非oracle(如polardb),请忽视错误信息:" + e.getMessage());
		}
		// clickhouse 数据库
		if (dbType == DBType.CLICKHOUSE && !isPolardb) {
			StringBuilder queryStr = new StringBuilder();
			queryStr.append(
					"select name COLUMN_NAME,comment COMMENTS,is_in_primary_key PRIMARY_KEY,is_in_partition_key PARTITION_KEY,type TYPE,default_expression DEFAULT_EXPRESSION from system.columns t where t.table=?");
			pst = conn.prepareStatement(queryStr.toString());
			pst.setString(1, tableName);
			rs = pst.executeQuery();
			filedsComments = (HashMap) DBUtil.preparedStatementProcess(null, pst, rs,
					new PreparedStatementResultHandler() {

						public void execute(Object obj, PreparedStatement pst, ResultSet rs) throws SQLException {
							HashMap filedHash = new HashMap();
							while (rs.next()) {
								TableColumnMeta colMeta = new TableColumnMeta();
								colMeta.setColName(rs.getString("COLUMN_NAME"));
								colMeta.setColRemark(StringUtil.clearMistyChars(rs.getString("COMMENTS"), " "));
								// 是否主键
								if (rs.getString("PRIMARY_KEY").equals("1")) {
									colMeta.setIsPrimaryKey(true);
								}
								if (rs.getString("PARTITION_KEY").equals("1")) {
									colMeta.setPartitionKey(true);
								}
								String typeName = rs.getString("TYPE");
								colMeta.setTypeName(typeName);
								colMeta.setColDefault(rs.getString("DEFAULT_EXPRESSION"));
								if (colMeta.getColDefault() != null && colMeta.getColDefault().equals("")) {
									if (typeName.toLowerCase().startsWith("nullable(")
											|| !colMeta.getTypeName().toLowerCase().equalsIgnoreCase("string")) {
										colMeta.setColDefault(null);
									}
								}
								filedHash.put(rs.getString("COLUMN_NAME"), colMeta);
							}
							this.setResult(filedHash);
						}
					});
		}
		final HashMap metaMap = filedsComments;
		String catalog = dbConfig.getCatalog();
		String schema = dbConfig.getSchema();
		// 获取具体表对应的列字段信息
		if ((dbType == DBType.MYSQL || dbType == DBType.MYSQL57) && !isPolardb) {
			rs = conn.getMetaData().getColumns(catalog, schema, tableName, "%");
		} else {
			// oracle 场景存在大小写问题
			if (toUpperCase) {
				rs = conn.getMetaData().getColumns((catalog == null) ? null : catalog.toUpperCase(),
						(schema == null) ? null : schema.toUpperCase(), tableName, null);
			} else {
				rs = conn.getMetaData().getColumns(catalog, schema, tableName, null);
			}
		}

		return (List) DBUtil.preparedStatementProcess(metaMap, null, rs, new PreparedStatementResultHandler() {
			public void execute(Object obj, PreparedStatement pst, ResultSet rs) throws SQLException {
				List result = new ArrayList();
				String isAutoIncrement;
				String colName;
				while (rs.next()) {
					TableColumnMeta colMeta;
					colName = rs.getString("COLUMN_NAME");
					if (metaMap == null) {
						colMeta = new TableColumnMeta();
						colMeta.setColName(colName);
						colMeta.setColDefault(clearDefaultValue(rs.getString("COLUMN_DEF")));
						colMeta.setColRemark(StringUtil.clearMistyChars(rs.getString("REMARKS"), " "));
					} else {
						colMeta = (TableColumnMeta) metaMap.get(colName);
						if (dbType != DBType.CLICKHOUSE) {
							if (colMeta != null && colMeta.getColDefault() == null) {
								colMeta.setColDefault(clearDefaultValue(rs.getString("COLUMN_DEF")));
							}
						}
					}
					if (colMeta != null) {
						colMeta.setDataType(rs.getInt("DATA_TYPE"));
						if (dbType != DBType.CLICKHOUSE) {
							colMeta.setTypeName(rs.getString("TYPE_NAME"));
						}
						colMeta.setLength(rs.getInt("COLUMN_SIZE"));
						colMeta.setPrecision(colMeta.getLength());
						colMeta.setScale(rs.getInt("DECIMAL_DIGITS"));
						colMeta.setNumPrecRadix(rs.getInt("NUM_PREC_RADIX"));
						try {
							isAutoIncrement = rs.getString("IS_AUTOINCREMENT");
							if (isAutoIncrement != null && (isAutoIncrement.equalsIgnoreCase("true")
									|| isAutoIncrement.equalsIgnoreCase("YES") || isAutoIncrement.equalsIgnoreCase("Y")
									|| isAutoIncrement.equals("1"))) {
								colMeta.setAutoIncrement(true);
							} else {
								colMeta.setAutoIncrement(false);
							}
						} catch (Exception e) {
						}
						if (dbType == DBType.ORACLE) {
							if (colMeta.getColDefault() != null
									&& colMeta.getColDefault().toLowerCase().endsWith(".nextval")) {
								colMeta.setAutoIncrement(true);
								colMeta.setColDefault(colMeta.getColDefault().replaceAll("\"", "\\\\\""));
							}
						}
						if (colMeta.getColDefault() != null && colMeta.getColDefault().equalsIgnoreCase("NULL")) {
							colMeta.setColDefault(null);
						}
						if (rs.getInt("NULLABLE") == 1) {
							colMeta.setNullable(true);
						} else {
							colMeta.setNullable(false);
						}
						result.add(colMeta);
					} else {
						err.println("表:" + tableName + " 对应的列:" + colName + "不在当前用户表字段内,请检查schema或catalog配置是否正确!");
						logger.info("表:" + tableName + " 对应的列:" + colName + "不在当前用户表字段内,请检查schema或catalog配置是否正确!");
					}
				}
				this.setResult(result);
			}

		});
	}

	/**
	 * @todo 处理sqlserver default值为((value))问题
	 * @param defaultValue
	 * @return
	 */
	private static String clearDefaultValue(String defaultValue) {
		if (defaultValue == null) {
			return null;
		}
		if (defaultValue.trim().equals("")) {
			return defaultValue;
		}
		String result = defaultValue;
		if (result.startsWith("NULL::")) {
			return null;
		}
		int brecketIndex = result.indexOf("(");
		// 针对postgresql
		if (brecketIndex != -1 && result.indexOf(")") != -1 && result.indexOf("::", brecketIndex) != -1) {
			result = result.substring(result.indexOf("(") + 1, result.indexOf("::", brecketIndex));
		}
		// postgresql
		if (result.indexOf("'") != -1 && result.indexOf("::") != -1) {
			result = result.substring(0, result.indexOf("::"));
		}
		if (result.startsWith("((") && result.endsWith("))")) {
			result = result.substring(2, result.length() - 2);
		}
		if (result.startsWith("(") && result.endsWith(")")) {
			result = result.substring(1, result.length() - 1);
		}
		if (result.startsWith("'") && result.endsWith("'")) {
			result = result.substring(1, result.length() - 1);
		}
		if (result.startsWith("\"") && result.endsWith("\"")) {
			result = result.substring(1, result.length() - 1);
		}
		return result.trim();
	}

	/**
	 * @todo 获取表的外键信息
	 * @param tableName
	 * @return
	 * @throws SQLException
	 */
	public static List getTableImpForeignKeys(String tableName) {
		try {
			ResultSet rs = conn.getMetaData().getImportedKeys(dbConfig.getCatalog(), dbConfig.getSchema(), tableName);
			List result = (List) DBUtil.preparedStatementProcess(null, null, rs, new PreparedStatementResultHandler() {
				public void execute(Object obj, PreparedStatement pst, ResultSet rs) throws SQLException {
					List result = new ArrayList();
					while (rs.next()) {
						TableConstractModel constractModel = new TableConstractModel();
						constractModel.setFkName(rs.getString("FK_NAME"));
						constractModel.setFkRefTableName(rs.getString("PKTABLE_NAME"));
						constractModel.setFkColName(rs.getString("FKCOLUMN_NAME"));
						constractModel.setPkColName(rs.getString("PKCOLUMN_NAME"));
						constractModel.setUpdateRule(rs.getInt("UPDATE_RULE"));
						constractModel.setDeleteRule(rs.getInt("DELETE_RULE"));
						result.add(constractModel);
					}
					this.setResult(result);
				}
			});
			return result;
		} catch (Exception e) {
		}
		return new ArrayList();
	}

	/**
	 * @todo 获取表主键被其他表关联的信息(作为其它表的外键)
	 * @param tableName
	 * @return
	 * @throws Exception
	 */
	public static List getTableExportKeys(String tableName) {
		try {
			ResultSet rs = conn.getMetaData().getExportedKeys(dbConfig.getCatalog(), dbConfig.getSchema(), tableName);
			List result = (List) DBUtil.preparedStatementProcess(null, null, rs,
					new PreparedStatementResultHandler() {
						public void execute(Object obj, PreparedStatement pst, ResultSet rs) throws SQLException {
							List result = new ArrayList();
							while (rs.next()) {
								TableConstractModel constractModel = new TableConstractModel();
								constractModel.setPkRefTableName(rs.getString("FKTABLE_NAME"));
								constractModel.setPkColName(rs.getString("PKCOLUMN_NAME"));
								constractModel.setPkRefColName(rs.getString("FKCOLUMN_NAME"));
								constractModel.setUpdateRule(rs.getInt("UPDATE_RULE"));
								constractModel.setDeleteRule(rs.getInt("DELETE_RULE"));
								result.add(constractModel);
							}
							this.setResult(result);
						}
					});
			return result;
		} catch (Exception e) {
		}
		return new ArrayList();
	}

	/**
	 * @todo 获取表的主键信息
	 * @param tableName
	 * @return
	 * @throws SQLException
	 */
	public static List getTablePrimaryKeys(String tableName) {
		int dbType = -1;
		try {
			dbType = DBUtil.getDbType(conn);
			boolean isPolardb = dbConfig.getUrl().toLowerCase().contains("polardb");
			ResultSet rs = null;
			List pkList = null;
			if (dbType == DBType.CLICKHOUSE) {
				rs = conn.createStatement()
						.executeQuery("select t.name COLUMN_NAME from system.columns t where t.table='" + tableName
								+ "' and t.is_in_primary_key=1");
			} else {
				try {
					rs = conn.getMetaData().getPrimaryKeys(dbConfig.getCatalog(), dbConfig.getSchema(), tableName);
				} catch (Exception e) {

				}
			}
			// 针对StarRocks场景
			if (rs == null && (dbType == DBType.MYSQL || dbType == DBType.MYSQL57) && !isPolardb) {
				rs = conn.createStatement().executeQuery("desc " + tableName);
				pkList = (List) DBUtil.preparedStatementProcess(null, null, rs, new PreparedStatementResultHandler() {
					public void execute(Object obj, PreparedStatement pst, ResultSet rs) throws SQLException {
						List result = new ArrayList();
						String field;
						while (rs.next()) {
							field = rs.getString("FIELD");
							if (rs.getBoolean("KEY")) {
								result.add(field);
							}
						}
						this.setResult(result);
					}
				});
			} else if (dbType == DBType.IMPALA) {
				rs = conn.createStatement().executeQuery("DESCRIBE " + tableName);
				pkList = (List) DBUtil.preparedStatementProcess(null, null, rs, new PreparedStatementResultHandler() {

					public void execute(Object obj, PreparedStatement pst, ResultSet rs) throws SQLException {
						List result = new ArrayList();
						String field;
						while (rs.next()) {
							field = rs.getString("NAME");
							if (rs.getBoolean("PRIMARY_KEY")) {
								result.add(field);
							}
						}
						this.setResult(result);
					}
				});
			} else {
				pkList = (List) DBUtil.preparedStatementProcess(null, null, rs, new PreparedStatementResultHandler() {
					public void execute(Object obj, PreparedStatement pst, ResultSet rs) throws SQLException {
						List result = new ArrayList();
						while (rs.next()) {
							result.add(rs.getString("COLUMN_NAME"));
						}
						this.setResult(result);
					}
				});
			}

			// 排除重复主键约束
			HashSet hashSet = new HashSet(pkList);
			return new ArrayList(hashSet);
		} catch (Exception e) {
			if (!(dbType == DBType.MYSQL || dbType == DBType.MYSQL57)) {
				e.printStackTrace();
			}
		}
		return new ArrayList();
	}

	/**
	 * @todo 获取表的主键约束名称
	 * @param tableName
	 * @return
	 * @throws SQLException
	 */
	public static String getTablePKConstraint(String tableName) throws Exception {
		String pkName = null;
		int dbType = DBUtil.getDbType(conn);
		if (dbType == DBType.CLICKHOUSE || dbType == DBType.IMPALA) {
			return pkName;
		}
		try {
			ResultSet rs = conn.getMetaData().getPrimaryKeys(dbConfig.getCatalog(), dbConfig.getSchema(), tableName);
			pkName = (String) DBUtil.preparedStatementProcess(null, null, rs, new PreparedStatementResultHandler() {
				public void execute(Object obj, PreparedStatement pst, ResultSet rs) throws SQLException {
					rs.next();
					this.setResult(rs.getString("PK_NAME"));
				}
			});
		} catch (Exception e) {
			if (!(dbType == DBType.MYSQL || dbType == DBType.MYSQL57)) {
				e.printStackTrace();
			}
		}
		return pkName;
	}

	public static int getDBType() throws Exception {
		return DBUtil.getDbType(conn);
	}

	public static String getDBDialect() throws Exception {
		return DBUtil.getCurrentDBDialect(conn);
	}

	public static List getIndexInfo(String tableName, String pkName) {
		List result = new ArrayList();
		List uniqueIndexes = getIndexInfo(tableName, pkName, true);
		Set indexNames = new HashSet<>();
		if (uniqueIndexes != null && !uniqueIndexes.isEmpty()) {
			for (IndexModel indexModel : uniqueIndexes) {
				if (!indexNames.contains(indexModel.getIndexName())) {
					indexModel.setIsUnique(true);
					result.add(indexModel);
					indexNames.add(indexModel.getIndexName());
				}
			}
		}
		List otherIndexes = getIndexInfo(tableName, pkName, false);
		if (otherIndexes != null && !otherIndexes.isEmpty()) {
			for (IndexModel indexModel : otherIndexes) {
				if (!indexNames.contains(indexModel.getIndexName())) {
					indexModel.setIsUnique(false);
					result.add(indexModel);
					indexNames.add(indexModel.getIndexName());
				}
			}
		}
		return result;
	}

	public static List getIndexInfo(String tableName, String pkName, boolean isUnique) {
		try {
			ResultSet rs = conn.getMetaData().getIndexInfo(dbConfig.getCatalog(), dbConfig.getSchema(), tableName,
					isUnique, true);
			List result = (List) DBUtil.preparedStatementProcess(null, null, rs,
					new PreparedStatementResultHandler() {
						public void execute(Object obj, PreparedStatement pst, ResultSet rs) throws SQLException {
							List result = new ArrayList();
							Map indexMap = new HashMap<>();
							String indexName;
							String columnName;
							String sortType;
							while (rs.next()) {
								indexName = rs.getString("INDEX_NAME");
								if ((indexName != null && !indexName.equalsIgnoreCase("PRIMARY")) && (pkName == null
										|| (pkName != null && !indexName.equalsIgnoreCase(pkName)))) {
									columnName = rs.getString("COLUMN_NAME");
									sortType = rs.getString("ASC_OR_DESC");
									if (sortType != null) {
										if (sortType.equalsIgnoreCase("A")) {
											sortType = "ASC";
										} else {
											sortType = "DESC";
										}
									} else {
										sortType = "";
									}
									IndexModel indexModel = indexMap.get(indexName);
									if (indexModel == null) {
										indexModel = new IndexModel();
										indexModel.setIndexName(indexName);
										indexModel.setSortTypes(new String[] { sortType });
										indexModel.setColumns(new String[] { columnName });
										indexModel.setIsUnique(rs.getBoolean("NON_UNIQUE"));
										indexModel.setTableName(tableName);
										result.add(indexModel);
									} else {
										int len = indexModel.getColumns().length;
										String[] columns = new String[len + 1];
										String[] sortTypes = new String[len + 1];
										System.arraycopy(indexModel.getColumns(), 0, columns, 0, len);
										System.arraycopy(indexModel.getSortTypes(), 0, sortTypes, 0, len);
										columns[len] = columnName;
										sortTypes[len] = sortType;
										indexModel.setColumns(columns);
										indexModel.setSortTypes(sortTypes);
									}
									indexMap.put(indexName, indexModel);
								}
							}
							this.setResult(result);
						}
					});
			return result;
		} catch (Exception e) {
		}
		return new ArrayList();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy