搜索函数

时间:2018-05-07 08:55:05

标签: java mysql sql swing jdbc

我想使用多个Java Swing组件执行搜索功能,用户可以搜索(名称/国籍/专业/经验),结果将显示在Jtable中。

enter image description here

我只是在苦苦寻求SQL查询,好像用户只输入了一个'name',没有数据会被检索,因为它会像这样(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 :(得分:2)

让我们看看你的问题:

   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的命名参数。

答案 1 :(得分:1)

下面的代码可能会给你预期的结果。

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());

试试这个

答案 2 :(得分:1)

在这种情况下,您有两个解决方案:

  1. 检查值是否为null将该部分附加到查询中,否则忽略它
  2. 第二个解决方案,您可以在查询中检查值是否为空。
  3. 我将给你一个关于第二个的例子,你可以使用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是否为空或者您传递的值是否为国籍,这样就可以避免空值。

    一些很好的参考资料: