今天我正在对我的代码进行 self 审查,代码对我来说看起来不太好(尽管它按预期工作)。所以我想要一个更好的方法来做同样的事情。 情况如下:
- 在我的网络服务中,客户端可以通过 n 个搜索条件对记录执行搜索操作(一个可能的条件可以是
给我所有名字包含 A 且指定为 Teacher 的员工
。所以对于这样的查询我有很多 if 语句相应地进行字符串查询。但这对我来说很难看。他们是否有任何方法可以使用PreparedStatement
实现此目的。
丑陋的代码如下所示
private String getSearchQuery(Staff staffEntity) {
boolean hasAnySearchParam = false;
String query = null;
StringBuilder querybuilder = new StringBuilder("select * from " + DBConstants.StaffBasicInfo.tableName + " left outer join " + DBConstants.StaffAdvInfo.tableName + " on "
+ DBConstants.StaffBasicInfo.staffId + " = " + DBConstants.StaffAdvInfo.staff_adv_info_staffId + " where");
if (staffEntity.getName() != null && (!staffEntity.getName().isEmpty())) {
querybuilder.append(" " + DBConstants.StaffBasicInfo.staffname + " Like '%" + staffEntity.getName() + "%'");
querybuilder.append(" and");
hasAnySearchParam = true;
}
if (staffEntity.getDesignation() != null && (!staffEntity.getDesignation().isEmpty())) {
querybuilder.append(" " + DBConstants.StaffBasicInfo.designation + " Like '%" + staffEntity.getDesignation() + "%'");
querybuilder.append(" and");
hasAnySearchParam = true;
}
if (staffEntity.getAge() != null) {
querybuilder.append(" " + DBConstants.StaffBasicInfo.age + " = " + staffEntity.getAge());
querybuilder.append(" and");
hasAnySearchParam = true;
}
if (staffEntity.getUsername() != null && (!staffEntity.getUsername().isEmpty())) {
querybuilder.append(" " + DBConstants.StaffAdvInfo.username + " Like '%" + staffEntity.getUsername() + "%'");
querybuilder.append(" and");
hasAnySearchParam = true;
}
if (staffEntity.getRole() != null && (!staffEntity.getRole().isEmpty())) {
querybuilder.append(" " + DBConstants.StaffAdvInfo.role + " Like '%" + staffEntity.getRole() + "%'");
querybuilder.append(" and");
hasAnySearchParam = true;
}
if (false == hasAnySearchParam) {
throw new IllegalArgumentException("Check Json: No parameter to search");
} else {
// need to clean query.
query = querybuilder.substring(0, querybuilder.length() - 3);
}
return query;
}
注意现在我更关心代码的清晰度、简单性和易用性,以后再考虑性能问题。
最佳答案
对于这种特殊情况,我会使用带有参数的静态查询,其中参数是从 java 设置的
WHERE
...
and (:userNameParam is null or staffname like concat('%',:staffnameParam,'%'))
and (:userNameParam is null or username like concat('%',:userNameParam ,'%'))
...
然后只需传递参数 userNameParam、userNameParam 等。如果它们为 null 或为空,则只需传递 null。
您的方式为 SQL 注入(inject)留下了可能性
关于java - 构建数据库查询的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23540593/