使用DatabaseMetaData获取数据库元数据来自动创建表等操作

背景:最近有这么一个需求,需要在serviceB服务器上的数据库databaseB中每月创建一个表tableB_month,然后每月将serviceA服务器上的数据库databaseA里的表tableA里面的数据导入到tableB_month数据库里面,数据库为MySQL数据库。还不给root权限账户,不能用Linux脚本实现了(本来我也不会 >-_->)!

查了点资料,找到Java里面的一个DatabaseMetaData类(谷歌版api:http://blog.fondme.cn:8000/apidoc/jdk-1.8-google/),可以使用。
然后就得到了如下代码,可惜的是并没有找到能完全区分出来UNIQUE KEY、KEY、 FULLTEXT KEY这三种索引类型的方法,所以下面的代码也是个半成品。代码里面的注释也挺详细了,有兴趣的可以看一下。



package com.netctrl.utils;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

import org.springframework.util.StringUtils;

public class TestConnectionMysql {
	public static void main(String[] args) throws Exception {
		// 驱动
		String driver = "com.mysql.jdbc.Driver";
		// 数据库连接
		String url = "jdbc:mysql://localhost:3306/test";
		// 用户名
		String user = "root";
		// 数据库密码
		String password = "123456";
		// 加载驱动
		Class.forName(driver);
		// 获取链接
		Connection connection = DriverManager.getConnection(url, user, password);
		//数据库名
		String tableName = "gov_vehicle_2018_05";

		DatabaseMetaData dBMetaData = connection.getMetaData();

		ResultSet colSet = dBMetaData.getColumns(null, "%", tableName, "%");

		String newTabaleName = tableName + "2018_16";
		// 拼成SQL语句
		StringBuilder sql = new StringBuilder();
		sql.append("CREATE TABLE `").append(newTabaleName).append("`"); // 建表
		sql.append("(");

		while (colSet.next()) {
			sql.append("`").append(colSet.getString("COLUMN_NAME")).append("` "); // 列名称
			sql.append(colSet.getString("TYPE_NAME")); // 列类型
			String typeName = colSet.getString("TYPE_NAME").trim();
			if(!"FLOAT".equals(typeName) && !"TIMESTAMP".equals(typeName)) {
				sql.append("(").append(colSet.getString("COLUMN_SIZE")).append(") "); // 列大小
			}else if("TIMESTAMP".equals(typeName)) {
				sql.append(" NULL ");
			}
			if ("0".equals(colSet.getString("NULLABLE"))) { // 是否允许使用空
				if (StringUtils.isEmpty(colSet.getString("COLUMN_DEF"))) { // 该列的默认值
					sql.append(" NOT NULL");
				} else {
					
					sql.append(" DEFAULT '").append(colSet.getString("COLUMN_DEF")).append("'");
				}
			} else {
				sql.append(" DEFAULT NULL ");
			}
			sql.append(" COMMENT ").append("'").append(colSet.getString("REMARKS")).append("' ,"); // 列注释
			// sql.append(colSet.getString("IS_AUTOINCREMENT")); // 该列是否自动增加 YES:自增,
			// NO:不自增,空字符串:不确定是否自增
		}
		sql.deleteCharAt(sql.length()-1);
		sql.append(")");

		colSet.close();

		String schema = null;

		// 检索给定表的索引和统计信息的描述。
		ResultSet indexInfo = dBMetaData.getIndexInfo(null, null, tableName, false, false);
		String indexstr = "";
		while (indexInfo.next()) {
			System.out.println("表名:" + indexInfo.getString("TABLE_NAME"));
			System.out.println("索引值不唯一:" + indexInfo.getString("NON_UNIQUE"));
			System.out.println("索引名称:" + indexInfo.getString("INDEX_NAME"));
			System.out.println("索引类型:" + indexInfo.getString("TYPE"));
			System.out.println("索引类别:" + indexInfo.getString("INDEX_QUALIFIER"));
			//就是这个地方,我数据库中的表里面有 UNIQUE KEY、KEY、 FULLTEXT KEY,
			//在这里无法区分出来,就无法生成准确的建表sql,所以就没有拼接到sql里面去
			int index = indexInfo.getInt("TYPE");
			switch (index) {
				case 0: {
					indexstr = "没有索引";
					break;
				}
				case 1: {
					indexstr = "聚集索引";
					break;
				}
				case 2: {
					indexstr = "哈希表索引";
					break;
				}
				case 3: {
					indexstr = "其它索引";
					break;
				}
			}
			System.out.println("索引中的列序列号:" + indexInfo.getString("ORDINAL_POSITION"));
			System.out.println("列名称:" + indexInfo.getString("COLUMN_NAME"));
			System.out.println("行数或索引中唯一值的数量:" + indexInfo.getString("CARDINALITY"));
			System.out.println("页数,否则是当前索引使用的页数:" + indexInfo.getString("PAGES"));
		}
		indexInfo.close();

		System.out.println("----------------主键列-----------------");

		// 检索给定表的主键列的描述。
		ResultSet primaryKeys = dBMetaData.getPrimaryKeys(null, null, tableName);
		while (primaryKeys.next()) {
			System.out.println("表目录:" + primaryKeys.getString("TABLE_CAT"));
			System.out.println("表格式:" + primaryKeys.getString("TABLE_SCHEM"));
			System.out.println("表名:" + primaryKeys.getString("TABLE_NAME"));
			System.out.println("列名:" + primaryKeys.getString("COLUMN_NAME"));
			System.out.println("主键中的序列号:" + primaryKeys.getString("KEY_SEQ"));
			System.out.println("主键名称:" + primaryKeys.getString("PK_NAME"));
		}
		primaryKeys.close();
		// System.out.println("\n建表: " + sql);

//		 执行建表操作
		System.out.println("\n建表: " + sql);
		 Statement st = connection.createStatement();
		 st.executeUpdate(sql.toString());
		 st.close();

		connection.close();

	}

}

若有哪位 大神知道怎么用DatabaseMetaData这个类或者其他的类能区分出来UNIQUE KEY、KEY、 FULLTEXT KEY这三种索引,还请不吝赐教,先在此拜谢!

你可能感兴趣的:(Java,mysql)