SQL-запрос для функции поиска - PullRequest
0 голосов
/ 07 мая 2018

Я хочу создать функцию поиска с несколькими компонентами Java Swing, где пользователь может выполнять поиск по (имя / национальность / специальность / опыт), и результаты будут отображаться в Jtable.

enter image description here

Я только борюсь с SQL-запросом, так как если бы пользователь вводил только «имя», никакие данные не будут извлечены, потому что он поступает в базу данных следующим образом (name, null, null, null), а я нет У меня есть нулевые значения в моей базе данных.

Поэтому я хочу получить все данные с этим именем независимо от других столбцов, но в то же время, если они также выбрали определенную специальность, например, я хочу получить все данные с выбранным именем И специальностью и т. Д. .

Надеюсь, вы понимаете мой вопрос.

Моя текущая инструкция SQL:

public ArrayList<Applications> getData(String name, String nationality, String specialty, String experience) {

   ArrayList<Applications> list = new ArrayList<Applications>();
   Connection con = getConnection();
   Statement st;
   ResultSet rows;

   try {
       st = con.createStatement();

       rows = st.executeQuery("SELECT * FROM applications WHERE name LIKE '%" +  name+"%'"
            + " AND (nationality LIKE '" +  nationality+"')"
            + " AND (specialty LIKE '" +  specialty+"')"
            + " AND (experience LIKE '" +  experience+"')");

       Applications applications;

       while(rows.next()) {
           applications = new Applications(
               rows.getInt("id"),
               rows.getString("name"),
               rows.getString("nationality"),
               rows.getString("Specialty"),
               rows.getString("experience")
           );

          list.add(applications);
       }   
   } catch (SQLException ex) {
       Logger.getLogger(MyQuery.class.getName()).log(Level.SEVERE, null, ex);
   }

   return list;
}

Ответы [ 3 ]

0 голосов
/ 07 мая 2018

В этом случае у вас есть два решения:

  1. Проверьте значения, если не пусто, добавьте эту часть к запросу, иначе проигнорируйте ее
  2. Второе решение, вы можете проверить, является ли значение пустым или нет в запросе.

Я приведу пример со вторым, вы можете использовать NamedParameterStatement это похоже на PrepapredStatement, чтобы избежать синтаксической ошибки и SQL-инъекции:

String query = "SELECT * FROM applications"
        + " WHERE (:name is null or name LIKE CONCAT('%', :name, '%')) "
        + " AND (:nationality is null or nationality LIKE :nationality)"
        + " AND (:specialty is null or specialty LIKE :specialty)"
        + " AND (:experience is null or experience LIKE :experience)";

NamedParameterStatement namedParametterStatement = 
                           new NamedParameterStatement(connection, query);

namedParametterStatement.setString("name", name);
namedParametterStatement.setString("nationality", nationality);
namedParametterStatement.setString("specialty", specialty);
namedParametterStatement.setString("experience", experience);

Обратите внимание на хитрость, например, здесь:

(:nationality is null or nationality LIKE :nationality)

Он проверит, является ли nationality нулевым, или национальность, например, значение, которое вы передаете, например, вы избегаете нулевого.


Несколько хороших ссылок:

0 голосов
/ 07 мая 2018

Давайте посмотрим на ваш запрос:

   rows = st.executeQuery("SELECT * FROM applications WHERE name LIKE '%" +  name+"%'"
        + " AND (nationality LIKE '" +  nationality+"')"
        + " AND (specialty LIKE '" +  specialty+"')"
        + " AND (experience LIKE '" +  experience+"')");

Здесь, поскольку был задан только name, остальные значения null. Если вы пишете этот код для тестирования:

String foo = null;
System.out.println(foo + "");

вывод будет

"нуль"

так, поскольку ваши значения null, сгенерированный запрос будет

   SELECT * FROM applications WHERE name LIKE '%Rowan Atkinson%'
        AND (nationality LIKE 'null')
        AND (specialty LIKE 'null')
        AND (experience LIKE 'null')

Прежде всего, давайте удостоверимся, что вы получите пустое String в случае null:

   rows = st.executeQuery("SELECT * FROM applications WHERE name LIKE '%" +  ((name == null) ? "" : name)+"%'"
        + " AND (nationality LIKE '" +  ((nationality == null) ? "" : nationality)+"')"
        + " AND (specialty LIKE '" +  ((specialty == null) ? "" : specialty)+"')"
        + " AND (experience LIKE '" +  ((experience == null) ? "" : experience)+"')");

Следующая проблема заключается в том, что вы ставите % только на name, что также неверно, поэтому давайте исправим это:

   rows = st.executeQuery("SELECT * FROM applications WHERE name LIKE '%" +  ((name == null) ? "" : name)+"%'"
        + " AND (nationality LIKE '%" +  ((nationality == null) ? "" : nationality)+"%')"
        + " AND (specialty LIKE '%" +  ((specialty == null) ? "" : specialty)+"%')"
        + " AND (experience LIKE '%" +  ((experience == null) ? "" : experience)+"%')");

и теперь прочитайте ответ YCF_L, чтобы использовать именованные параметры для PreparedStatement.

0 голосов
/ 07 мая 2018

Ниже код может дать вам ожидаемый результат.

StringBuilder sql=new StringBuilder("SELECT * FROM applications WHERE 1=1 ");
        if(!name.isEmpty()){
            sql.append(" AND name LIKE '%" +  name+"%'");
        }
        if(!nationality.isEmpty()){
            sql.append(" AND (nationality LIKE '" +  nationality+"')");
        }
        if(!specialty.isEmpty()){
            sql.append(" AND (specialty LIKE '" +  specialty+"')");
        }
        if(!experience.isEmpty()){
            sql.append(" AND (experience LIKE '" +  experience+"')");
        }

        rows = st.executeQuery(sql.toString());

Попробуйте это

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...