最近在做项目的时候因为经常会碰到代码在开发环境可以正常运行,但是到了测试和预生产环境运行报错,但是测试环境和预生产环境的网络与本地是隔离的,无法直接连接数据库,于是想到了把数据拷贝一份到开发环境来,但是有些表的字段两三百个,手工拷贝实在太浪费时间精力,还容易出错,于是就想到了提供一个接口,传入表表名和字段名以及字段值来查询需要的数据然后生成insert语句,拿到开发环境来执行,这个过程的思路如下:
1、获取数据表的元数据,也就是字段名和对应的数据类型
2、查询一个样例数据(目标数据)
3、拼装insert语句返回
这里的重难点在第一步,一共有三种方式如下:
第一种:通过DatabaseMetaData metaData = connection.getMetaData();来获取
public static void main(String[] args) throws Exception {
String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/test";
String userName = "root";
String password = "tianjun";
List<String> columns = new LinkedList<>();
try (Connection connection = DriverManager.getConnection(jdbcUrl, userName, password)) {
DatabaseMetaData metaData = connection.getMetaData();
ResultSet rs = metaData.getColumns(null, "test", "int_test_1", null);
while (rs.next()) {
String columnName = rs.getString("COLUMN_NAME");
String dataType = rs.getString("TYPE_NAME");
columns.add(columnName);
System.out.println("Column Name: " + columnName + ", Data Type: " + dataType.split(" ")[0]);
}
} catch (SQLException e) {
e.printStackTrace();
}
System.err.println(columns.size());
}
这种方式我在本地跑的好好的,但是到了测试环境和预生产环境会导致columns 的数据量翻倍,没找到原因
第二种:通过SHOW COLUMNS FROM TABLE_NAM
public static void main(String[] args) throws Exception {
String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/test";
String userName = "root";
String password = "tianjun";
List<String> columns = new LinkedList<>();
try (Connection connection = DriverManager.getConnection(jdbcUrl, userName, password)) {
DatabaseMetaData metaData = connection.getMetaData();
String columnSql = "SHOW COLUMNS FROM int_test_1";
// ResultSet rs = metaData.getColumns(null, "test", "int_test_1", null);
ResultSet rs = connection.prepareStatement(columnSql).executeQuery();
while (rs.next()) {
String columnName = rs.getString("Field");
String dataType = rs.getString("Type");
columns.add(columnName);
System.out.println("Column Name: " + columnName + ", Data Type: " + dataType.split(" ")[0]);
}
} catch (SQLException e) {
e.printStackTrace();
}
System.err.println(columns.size());
}
第三种:从information_schema库去查:SELECT COLUMN_name,data_type FROM information_schema.columns where table_name='int_test_1';
但是这种查出来的顺序与建表语句不一样,所以就没有用这种了,最终采用的是第二种方式