Как удалить условие из условия where, если определенное значение равно нулю (с использованием подготовленных операторов) - PullRequest
0 голосов
/ 15 ноября 2018

Получение параметров из запроса:

String city = request.getParameter("city");
int price = Integer.parseInt(request.getParameter("price").toString());
int guests ... etc
date init_date... etc
date end_date...etc
initDate = parse init_date with simpledateformater...etc
endDate = parse init_date with simpledateformater...etc

Давайте подготовим следующее состояние:

String getResult = "SELECT id_housing, name, description_short, price, 
photo FROM housing WHERE city = ? AND init_date <= ? AND end_date >= ? AND 
price = ? AND guests >= ?";

PreparedStatement stmt = con.prepareStatement(getResult);

stmt.setString(1, city);
stmt.setDate(2, new java.sql.Date(initDate.getTime()));
stmt.setDate(3, new java.sql.Date(endDate.getTime()));
stmt.setInt(4, price);
stmt.setInt(5, guests);
ResultSet rs = stmt.executeQuery();

Вопрос в том, как я могу удалить город или цену или любое значение после предложения WHERE, если значение равно нулю. Например, если мой пользователь не хочет писать какой-либо текст во входном тексте города, request.getParameter будет нулевым (или пустой строкой "", я не знаю). В таком случае я хочу убрать город =? условие из подготовленного оператора, поэтому запрос будет возвращать строки с любым значением города).

Я пытался с

WHERE city = IFNULL(? , *) AND ...

Но не работает.

Ответы [ 4 ]

0 голосов
/ 15 ноября 2018

Одним из способов достижения этого является создание заглушки / шаблона запроса, в который вы динамически добавляете условие WHERE. Вы храните переменные связывания в карте, которая отображает индекс переменной в соответствующее значение:

String queryStub = "SELECT id_housing, name, description_short, price, " 
    + "photo FROM housing WHERE 1=1";

Map<Integer, Object> bindVariables = new HashMap<>();
StringBuilder sb = new StringBuilder(queryStub);
int paramIndex = 1;

if (city != null && !city.isEmpty()) {
   sb.append(" AND city = ?")
   bindVariables.put(paramIndex++, city);
}

// ... handle the other, possibly empty inputs

try (PreparedStatement stmt = con.prepareStatement(sb.toString());) {

    for (Map.Entry<Integer, Object> e : bindVariables.entrySet()) {
        stmt.setObject(e.getKey(), e.getValue());
    }

    ResultSet rs = stmt.executeQuery();
    // ...
} 
0 голосов
/ 15 ноября 2018

К сожалению. вам нужен отдельный запрос для этого случая.

Это одна из причин, по которой часто не рекомендуется использовать необработанный JDBC для доступа к базе данных. При сложных запросах вы получаете кучу склонной к ошибкам логики, которая строит фрагменты и объединяет их. Если у вас не много таких случаев, просто используйте два разных запроса.

Но если вы продолжите работать с большим количеством этих запросов, то существует множество библиотек, которые могут помочь во всем - от открытия соединений до безопасного выполнения запросов без необходимости создавать различные запросы с использованием необработанных строк. Jooq и mybatis приходят на ум.

0 голосов
/ 15 ноября 2018
String getResult = "SELECT id_housing, name, description_short, price, 
    photo FROM housing WHERE init_date <= ? AND end_date >= ? AND 
    price = ? AND guests >= ?";
if(city != null && !city.isempty()){
    getResult += " AND city = ? "
}

PreparedStatement stmt = con.prepareStatement(getResult);
if(city != null && !city.isempty()){
    stmt.setString(1, city);
}
0 голосов
/ 15 ноября 2018

Просто измените строку getResult, когда значение города равно нулю. Примерно так:

if(city == null) {
   getResult = "SELECT id_housing, name, description_short, price, photo FROM housing AND init_date <= ? AND end_date >= ? AND price = ? AND guests >= ?";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...