我知道硬编码任何东西都是不好的。通常我们通过配置文件来完成大部分环境变量。例如,数据库属性,项目配置,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 :(得分:2)
使用从字符串创建的语句有一个更严重的问题(即使它们是常量) - 你可能会打开SQL injection的大门。从安全角度来看,最好使用prepared statements代替,通过setXXX()
方法设置参数,而不是像问题中那样连接字符串。
最好将准备好的语句的文本定义为使用它的类中的常量字符串,并使用参数的占位符。例如:
private static final String query =
"update dbName.tableName set field = ? where condition = ?";
答案 1 :(得分:1)
tableSgsnMapping
的值始终为ConstantManager.TABLE_SGSN_MAPPING
?然后我会使用这个常量,可能作为静态导入来节省一些空间。将其重新分配给局部变量可能会使读者感到困惑,如果其值被意外更改,则会引入错误。
答案 2 :(得分:0)
表格的名称可能不会像您说的那样改变。但谁知道未来?
但我的主要观点ConstantManager.TABLE_SGSN_MAPPING
是表名和列名通常在代码中的不同语句和位置中多次使用。使用常量,您可以确定,一个中很少使用关于这些事情的SQL语句。我在这个角落最喜欢的是:表名是否为复数形式? (“客户”与“客户”)。我根本不想再次考虑这一点 - 通过使用常量。