문제

Today i was doing self-review of my code and code didn't look nice to me (Although it is working as intended). So i want a better way of doing the same. Following is the case:

  1. In my webservice, client can perform search operation on records by n number of search criteria ( one possible criteria can be get me all the staff whose name contains A and who has designation Teacher. So for such query i have many if statements that is making string query accordingly. but this is looking ugly to me. Is their any way to achieve this using PreparedStatement.

Ugly code looks like below

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;
}

Note Right now i am more concerned about code clarity, simplicity and ease to use, i can think of performance issues later.

도움이 되었습니까?

해결책

For this particular case I would use static query with params where params are set from java

WHERE
...
  and (:userNameParam is null or staffname like concat('%',:staffnameParam,'%'))
  and (:userNameParam is null or username like concat('%',:userNameParam ,'%'))
...

Then just pass parameters userNameParam, userNameParam etc. If they are null or empty just pass null.

Your way leaves possibility for SQL injection

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top