因为数据库的更新,新的数据库是基于原有的数据库,只是新的数据库对部分表进行了修改,并加入了一些新的表。但原数据库中的数据是比需要导入到新的数据库中。手工的话,工作量太大,也没有什么通用性。所有就想用JAVA代码来实现此功能。
先把原有的数据库数据导出到一个文件中,再用java代码来读取文件中的insert语句,并执行。由于某些表的数据量有点多,就会出现多次 insert 同一表的语句。基于不想统计重复表,刚开始时是采用了Map 和HashMap的方式。因为构想是一个Key 对应多个Value。后面陈部指导我说,Map一般是适用数据量是W级别的,他的原理是牺牲空间来换取时间(O(1))。后面采取了用Bean来取代的办法,即定义了2个属性,一个tableName,一个value数组。
下面是实现插入的代码:
public class SqlInsertReader {
public static List<TableStatement> getSqls(String fileName) throws FileNotFoundException, IOException
{
List<TableStatement> tables = new LinkedList<TableStatement>();
FileReader fileReader = new FileReader(fileName);
BufferedReader reader = new BufferedReader(fileReader);
String record = null;
String tableName = null;
StringBuffer sqlBuffer = new StringBuffer();
TableStatement table = null;
boolean isInsertStatement = false;
while ((record = reader.readLine()) != null) {
if (record.indexOf("INSERT") != -1) {
isInsertStatement = true;
tableName=getTableName(record);
table=find(tables,tableName);
}
if (isInsertStatement) {
sqlBuffer.append(record);
if (record.indexOf(";") != -1) {
table.getSqlValues().add(adjustSQL(tableName, sqlBuffer.toString()));
isInsertStatement = false;
//清空
sqlBuffer = new StringBuffer();
}
}
}
return tables;
}
private static String getTableName(String record)
{
String strTemp = record.substring(record.indexOf(".") + 1);
String []aString = strTemp.split(" ");
return aString[0].replaceAll("`", "");
}
private static TableStatement find(List<TableStatement> tables, String tableName) {
//遍历tables,查找和tableName相同的元素,返回;
//如果找不到,则创建一个TableStatement对象,并加入到tables中,然后返回
for (TableStatement table : tables) {
if (table.getTableName().equals(tableName)) {
return table;
}
}
TableStatement statement = new TableStatement();
statement.setTableName(tableName);
tables.add(statement);
return statement;
}
private static String adjustSQL(String tableName, String sql) {
//删除 `OA`.
sql = sql.replaceAll("`OA`.", "");
//Project表的数据移动数据的位置
if ("Project".equals(tableName)) {
StringBuffer buffer = new StringBuffer();
String []aString = sql.split("[()]");
buffer.append(aString[0]);
for(int i=1;i<aString.length;i++){
if(aString[i].length()>2){
buffer.append(generateNewRecord(aString[i]));
buffer.append(",");
}
}
buffer.setCharAt(buffer.length()-1, ';');
return buffer.toString();
//return buffer.toString().substring(0, buffer.toString().length()-1)+";";
}
return sql;
}
//生成专门用于Project表的Insert语句的一行记录的sql语法,
//比如(xx,xxx,xxxx),调整了字段位置,以适应Alpha3数据库的变化
private static String generateNewRecord(String sql){
StringBuffer buffer = new StringBuffer();
String[] sqlString = sql.split(",");
buffer.append("(");
buffer.append(sqlString[0]);
buffer.append(",");
buffer.append(sqlString[6]);
buffer.append(",");
buffer.append(sqlString[1]);
buffer.append(",");
buffer.append(sqlString[2]);
buffer.append(",");
buffer.append(sqlString[3]);
buffer.append(",");
buffer.append(sqlString[4]);
buffer.append(",");
buffer.append(sqlString[5]);
buffer.append(")");
return buffer.toString();
}
}
在主函数出调用代码如下:
//把传入的文件作为参数(项目名称--属性--运行--参数(Netbeans)) List<TableStatement> tables = SqlInsertReader.getSqls(args[0]);
for (TableStatement table : tables) {
for (String sql : table.getSqlValues()) {
errorSql = sql;
statement = connection.prepareStatement(sql);
statement.executeUpdate();
}
}
因为有外键约束所以写了如下代码:
private static void adjustInsertTableOrder(String tableName, int index, List<TableStatement> tables) {
for (int j = 0; j < tables.size(); j++) {
if (tableName.equals(tables.get(j).getTableName())) {
//把对象删除之前,先保存下来
TableStatement employeeTable = tables.get(j);
tables.remove(j);
tables.add(index, employeeTable);
return;
}
}
}
写此文章也算是对自己的一次总结,也希望能给大家带来帮助。呵~