2014-09-01 66 views
0

所以我目前正在其中包括来自数个GZIP使用JDBC压缩CSV文件更新H2数据库的项目。我注意到CSV文件的处理过程保持不变。只有填写PreparedStatement对象的部分才真正有所不同。下面的代码片段,我使用:重构类似CSV处理

InputStream in = getStream(world.getUrl(), true, Configuration.GET_PLAYER_COMPRESSED); 
Scanner sc = new Scanner(in); 
PreparedStatement stmt = con.prepareStatement(SQL_UPDATE_PLAYER); 

String[] line; 
int i = 0; 
while (sc.hasNextLine()) { 
    try { 
     line = sc.nextLine().split(","); 

    { //this code differs from the rest 
     stmt.setString(1, world.getIdentifier()); 
     stmt.setInt(2, Integer.valueOf(line[0])); 
     stmt.setString(3, URLDecoder.decode(line[1], "UTF-8")); 
     if ("0".equals(line[2])) { 
      stmt.setNull(4, Types.INTEGER); 
     } else { 
      stmt.setInt(4, Integer.valueOf(line[2])); 
     } 
    } 
    stmt.addBatch(); 
    if (++i >= 1000) { 
     stmt.executeBatch(); //execute batch every 1000 entries 
     i=0; 
    } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
stmt.executeBatch(); 
stmt.close(); 
sc.close(); 

它是通过回调对象访问此问题,就像在下面的例子中的好办法?

Callback callback = new Callback() { 

    protected int i; 
    protected PreparedStatement stmt; 

    //called before processing 
    public void preProcess() { 
    int i = 0; 
    //initialisation or whatever 
    } 

    //called on every line 
    public void processLine(String[] line) { 
    stmt.setString(1, world.getIdentifier()); 
    // [...] 
    stmt.addBatch() 
    if(++i >= 1000) { 
     stmt.executeBatch(); 
     i = 0; 
    } 
    } 

    //called after processing lines 
    protected void postProcess() { 
    stmt.executeBatch(); 
    } 
} 

processCsv(inputStream, callback); 
+0

外包????????????????? – Leo 2014-09-01 18:27:21

+0

我的意思是像冗余代码打包到一个地方。不知道英文中的确切术语。 – Dreistein 2014-09-01 18:32:00

+0

*重构*。我已经相应地重发了你的帖子。 – khampson 2014-09-01 18:39:12

回答

0

我建议使用模板方法。为每种预准备语句的类型创建处理对象的子类。

在基类中。

protected abstract void processLine(PreparedStatement stmt, String[] line) 
    throws SQLException, UnsupportedEncodingException; 

public void parse() throws SQLException 
{ 
InputStream in = getStream(world.getUrl(), true, Configuration.GET_PLAYER_COMPRESSED); 
Scanner sc = new Scanner(in); 
PreparedStatement stmt = con.prepareStatement(SQL_UPDATE_PLAYER); 

String[] line; 
int i = 0; 
while (sc.hasNextLine()) { 
    try { 
     line = sc.nextLine().split(","); 

    { 
     processLine(stmt, line); 
    } 
    stmt.addBatch(); 
    if (++i >= 1000) { 
     stmt.executeBatch(); //execute batch every 1000 entries 
     i=0; 
    } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
stmt.executeBatch(); 
stmt.close(); 
sc.close(); 
} 

在上例中的子类中。

protected void processLine(PreparedStatement stmt, String[] line) 
     throws SQLException, UnsupportedEncodingException 
{ 
    //this code differs from the rest 
     stmt.setString(1, world.getIdentifier()); 
     stmt.setInt(2, Integer.valueOf(line[0])); 
     stmt.setString(3, URLDecoder.decode(line[1], "UTF-8")); 
     if ("0".equals(line[2])) { 
     stmt.setNull(4, Types.INTEGER); 
     } else { 
     stmt.setInt(4, Integer.valueOf(line[2])); 
     } 
}