java - 构建数据库查询的设计模式

标签 java mysql sql prepared-statement

今天我正在对我的代码进行 self 审查,代码对我来说看起来不太好(尽管它按预期工作)。所以我想要一个更好的方法来做同样的事情。 情况如下:

  1. 在我的网络服务中,客户端可以通过 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/

相关文章:

java - 什么是 NullPointerException,我该如何解决?

java - 由 : java. sql.SQLException : ORA-06550: line 1, 第 7 列引起:PLS-00306:调用 'PR_SP_FAHMI' 时参数数量或类型错误

java - 如何使用 Java 流在集合中找到最小的 BigDecimal 字段?

java - 将 JsonNode 对象转换为 Map

mysql - hibernate 前 N 行 HQL 查询

Mysql查询选择只有字母字符的列

mysql - 在mysql中选择时间之间的记录

php - 如何插入连接的用户的数据库ID?

将 Inf、NAN 和 -Inf 插入 sqlite3 数据库的 SQL 命令

sql - hive 条件时的两种情况