2011-05-16 69 views
2

我知道硬編碼任何東西都不好。通常我們通過配置文件來完成大部分的環境變量。例如,數據庫屬性,項目配置,log4j,輸入,輸出。今天這種編程風格太多了嗎?

但我見過有人寫這樣的代碼:

public void updateExistedRecord(SgsnMapping sgsnMapping) throws Exception { 
     PreparedStatement ps = null; 

     try { 
      String updateSql = ""; 
      updateSql += "UPDATE " + schema + "." + tableSgsnMapping + " SET "; 
      //other where clause 

      ps = dbConn.prepareStatement(updateSql); 

      ps.executeUpdate(); 
     } catch (Exception ex) { 
      logger.error("Error when update an existing record on " + tableSgsnMapping + " table.\n" + ex.getMessage(), ex); 
      throw ex; 
     } finally { 
      SqlHelper.close(ps); 
     } 
    } 

的重點是放在桌子上 - tableSgsnMapping,它是寫在這樣的方式與其他地方:

private String tableSgsnMapping = ConstantManager.TABLE_SGSN_MAPPING; 

反過來,該TABLE_SGSN_MAPPING是定義其它地方:

public final static String TABLE_SGSN_MAPPING = "OBDUA_SGSN_MAPPING"; 

是不是太多了?該表不會改變它的名字,它會一直存在。爲什麼不在程序中硬編碼?爲什麼?

+0

表不會改變它們的名字,但是在代碼中可以有多個表名的引用,即常量可以用在多個地方。你真的不需要私人String tableSgsnMapping = ConstantManager.TABLE_SGSN_MAPPING和ConstantManager.TABLE_SGSN_MAPPING可以被直接使用,並且通過使用靜態導入可以進一步使用,你可以將它縮減爲TABLE_SGSN_MAPPING – 2011-05-16 07:28:24

+0

最適合回答爲什麼問題的人是誰寫了那個代碼。你爲什麼不問他?你們倆都比我們以往任何時候都更瞭解這個項目的特殊情況。 – meriton 2012-02-11 16:00:32

回答

1

tableSgsnMapping的值始終爲ConstantManager.TABLE_SGSN_MAPPING?然後我會使用這個常量,也許作爲一個靜態導入來節省一些空間。將其重新分配給本地變量可能會使讀者感到困惑,並且如果其值被意外更改,則會引入錯誤。

2

使用從字符串創建的語句存在更嚴重的問題(即使它們是常量) - 您可能會打開SQL injection的大門。從安全角度來看,最好使用prepared statements代替,通過setXXX()方法設置參數,而不是像問題中那樣連接字符串。

將準備好的語句的文本定義爲正在使用的類中的常量字符串,並使用參數的佔位符是個好主意。例如:

private static final String query = 
"update dbName.tableName set field = ? where condition = ?"; 
+1

好點。 'PreparedStatements'由DBMS更高效地執行。示例中使用了 – 2012-02-11 15:58:57

+0

PreparedStatements _are_。而SQL注入通常關注用戶輸入錯誤,而不是關於開發團隊不信任其他類常量的破壞。海事組織這是對正常使用情況偏執 – 2012-02-11 15:59:49

0

表的名稱可能不會像你說的那樣改變。但誰知道未來?

但我的主要觀點親ConstantManager.TABLE_SGSN_MAPPING是表名和列名通常在不同的語句和地方在代碼中使用多次。使用常量可以肯定,中沒有輸入錯誤,其中一個很少使用關於這些東西的SQL語句。我最喜歡的角落是:表格名稱是複數形式還是不是? (「客戶」與「客戶」)。我只是不想再次考慮這一點 - 通過使用常量。