公司里面对公用数据库的访问有很多限制,因为涉及到性能问题。一般程序用到的就只有几张表。为了更自由地访问数据,一般都需要作数据导出。
用程序实现数据导出,有以下几个问题:
用程序导数据,特别是增量导数据,是容易丢失数据的。我的处理方法是利用数据库表的AddTime字段。每次增量导入时,从dest表中取得最大时间,如果不存在(空表),则指定人工指定一个时间点。导入的时间要比最大时间小几秒钟,我定义的是5秒。
数据插入冲突也是比较容易出现的问题,解决方法是Insert If Not Exist。 对应到sql语句是:
insert into table_name (id,name) select 2,‘a‘ where not exists (select 1 from table_name where id = 2)
为了提高性能,最好用增量的方式。Java代码如下:
while(rs.next()){
++queryCount;
for(int i=1;i<=count;i++){
destPs.setObject(i, rs.getObject(i));
}
destPs.setObject(count+1, rs.getObject(pk));
destPs.addBatch();
if(batchSize%100==0){
destPs.executeBatch();
}
}
destPs.executeBatch();一般导数据的逻辑都是一样的,只是表不一样而已。这样的话,在程序实现的时,通用性就显得很重要,不然冗余代码会很多,程序也不好维护。一般的作法是把sql语句抽象出来。Insert语句由表结构生成。生成的Insert语句代码如下:
/*
* 生成插入语句
* @param tag 对于设置了主键自动增长的表,需要
* set identity_insert "+tableName+" ON
* */
public String sqlGenerate(int count,ResultSetMetaData rsd,String tableName,String pk,boolean tag) throws SQLException{
String sql="";
if(tag){
sql="set identity_insert "+tableName+" ON;";
}
sql+=" insert into "+tableName;
//columns
sql+="("+rsd.getColumnName(1);
for(int i=2;i<=count;i++){
sql+=‘,‘;
sql+=rsd.getColumnName(i);
}
sql+=")";
//values
sql+="select ?";
for(int i=2;i<=count;i++){
sql+=",?";
}
sql+=" where not exists (select 1 from "+tableName+" where "+pk+" = ? )";
return sql;
}这样的话,整个程序就变得很简洁。其实第四点是根据第二点的结构生成的。
本文出自 “每天进步一点点” 博客,请务必保留此出处http://sbp810050504.blog.51cto.com/2799422/1410754
原文:http://sbp810050504.blog.51cto.com/2799422/1410754