这样的编程风格是不是太多了?
我知道硬编码任何东西都是不好的。通常我们大部分的环境变量都是通过配置文件来完成的。例如,数据库属性、项目配置、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";
是不是太过分了?该表不会更改其名称,并且将始终存在。为什么不直接将其硬编码到程序中呢?为什么?
I know it is bad to hard code anything. Usually we do most of the environment variable by config file. For example, database property, project config, log4j, input, output.
But today I seen someone write code like this:
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);
}
}
The focus is on the table - tableSgsnMapping, it is written is other place in such way:
private String tableSgsnMapping = ConstantManager.TABLE_SGSN_MAPPING;
In turn, the TABLE_SGSN_MAPPING is define in other place:
public final static String TABLE_SGSN_MAPPING = "OBDUA_SGSN_MAPPING";
Isn't that too much? The table won't change its name and it will be always there. Why don't just hard code it in the program? Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用从字符串创建的语句(即使它们是常量)存在一个更严重的问题 - 您可能会打开 SQL注入。从安全角度来看,最好使用准备好的语句,通过 setXXX() 方法设置参数,而不是像问题中那样连接字符串。
最好将准备好的语句的文本定义为使用它的类中的常量字符串,并带有参数的占位符。例如:
There's a more serious problem with using statements created from Strings (even if they're in constants) - you might open the door to an SQL injection. From the security viewpoint, it's better to use prepared statements instead, setting the parameters via the
setXXX()
methods, not concatenating strings like in the question.And it's a good idea to have the text of the prepared statement defined as a constant string in the class where it's being used, with placeholders for the parameters. For example:
tableSgsnMapping
的值始终是ConstantManager.TABLE_SGSN_MAPPING
?然后我会使用这个常量,也许作为静态导入来节省一些空间。将其重新分配给局部变量可能会让读者感到困惑,并且如果意外更改其值,则会导致错误。The value of
tableSgsnMapping
is alwaysConstantManager.TABLE_SGSN_MAPPING
? Then I'd use this constant, maybe as a static import to save some space. Reassigning it to a local variable might be confusing to readers and introduce errors if its value is accidentally changed.表的名称可能不会像你所说的那样改变。但谁知道未来呢?
但我的主要观点是,表名和列名通常在代码中的不同语句和位置中多次使用。使用常量,您可以确定在关于这些事情的很少使用的 SQL 语句中没有拼写错误。在这个角落我最喜欢的是:表名是否为复数形式? (“客户”与“顾客”)。我只是不想每次都通过使用常量来思考这个问题。
The name of the table might not change as you say. But who knows the future?
But my main point pro
ConstantManager.TABLE_SGSN_MAPPING
is that table names and column names are usually used several times in different statements and places in the code. Using constants you can be sure, that there are no typos in one seldom used SQL statement regarding these things. My favourite in this corner is: Was the table name in plural form or not? ("customers" vs. "customer"). I simply don't want to think about that every time again - by using constants.