我想使用多个Java Swing组件执行搜索功能,用户可以搜索(名称/国籍/专业/经验),结果将显示在Jtable中。
我只是在苦苦寻求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;
}
答案 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)
在这种情况下,您有两个解决方案:
我将给你一个关于第二个的例子,你可以使用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
是否为空或者您传递的值是否为国籍,这样就可以避免空值。
一些很好的参考资料: