【问题标题】:How to form a SQL query dynamically based on the input field values如何根据输入字段值动态形成 SQL 查询
【发布时间】:2015-05-01 15:51:15
【问题描述】:

我有三个字段

 String stateID = "";
 String  districtID = "";
 String    talukaID = "";

这三个字段可以为空也可以有值

表的描述是

desc tbl_dealer

contactName
phone1
stateID
districtID
talukMandalID

根据收到的值,我必须动态编写 SQL 查询

根据收到的值,我必须动态编写 SQL 查询

例如

如果三个都是空的

select contactName , phone1 from tbl_dealer 

如果 stateID 为空,则(从查询中删除状态)

select contactName , phone1 from tbl_dealer where districtID = "'+districtID+'" AND talukaID = "'+talukaID+'"

对于所有情况都类似

请告诉我如何有效地写这个,

【问题讨论】:

    标签: java


    【解决方案1】:

    我建议,首先创建一个方法:

    private void appendFilter(StringBuilder sb, String fieldName, String fieldValue) {
        if(fieldValue != null && !fieldValue.trim().equalsIgnoreCase("")) {
            sb.append("AND "+fieldName+"='"+fieldValue+"'");
        }
    }
    

    那就用这个方法:

    StringBuilder sb = new StringBuilder();
    sb.append("select contactName , phone1 from tbl_dealer where 1=1 ");
    appendFilter(sb, "districtID", districtID);
    appendFilter(sb, "stateID", stateID);
    appendFilter(sb, "talukaID", talukaID);
    final String query=sb.toString();
    

    【讨论】:

    • 我建议在这里使用 StringBuilder 而不是 StringBuffer。 StringBuffer 是同步的,因此性能较低。
    • 哦!是的,请使用 StringBuilder。
    • 虽然您可以使用此方法构建查询,但您绝对不应该在字段中推送,否则您将面临 SQL 注入攻击。您应该使用占位符和 PreparedStatement
    • 没错,我们可以尝试类似的方法来构建准备好的语句。看着想要的输出,我做到了
    • 此外,正如@MrWiggles 所提到的,为了避免SQL 注入,您可以查看jOOQhibernate 或任何其他ORM。自己处理 jdbc 的东西有点乏味,尤其是连接关闭等。
    【解决方案2】:

    您应该使用带有绑定变量的PreparedStatement 来消除 SQL 注入的可能性(并使数据库能够缓存查询):

    PreparedStatement ps = null;
    try {
        List<String> bindVariables = new ArrayList<>();
        StringBuilder query = new StringBuilder(
            "select contactName, phone1 from tbl_dealer WHERE 1=1");
    
        if (stateID.length > 0) {
            query.append(" AND stateID = ?");
            bindVariables.add(stateID);
        }
        if (districtID.length > 0) {
            query.append(" AND districtID = ?");
            bindVariables.add(districtID);
        }
        if (talukaID.length > 0) {
            query.append(" AND talukaID = ?");
            bindVariables.add(talukaID);
        }
        ps = myConnection.prepareStatement(query.toString());
    
        for (int i = 0; i < bindVariables.size(); i++) {
            // variables are indexed from 1 in JDBC
            ps.setString(i+1, bindVariables.get(i));
        }
        ResultSet rs = ps.executeQuery();
    
        // iterate over the result set here
    
        rs.close();
    } finally {
        if (ps != null) {
            ps.close();
        }
    }
    

    如果您要在 WHERE 条件中使用更多列,则可以通过引入辅助方法来删除代码中的一些重复项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-13
      • 2014-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多