避免从条件语句中进行比较

Posted

技术标签:

【中文标题】避免从条件语句中进行比较【英文标题】:Avoid comparison from conditional statements 【发布时间】:2014-05-20 17:34:56 【问题描述】:

您好,我正在尝试根据品牌、口味、价格、尺寸、类型过滤记录。我正在使用单个表单来处理这个问题,所以如果用户仅按品牌过滤,那么其他选项(如价格、风味)将被取消选中,所以我正在检查品牌、风味或价格是否为空。我得到了解决方案,但我做了很多所有情况的比较。我需要一个解决方案来减少比较。我正在使用以下代码

  public List<Products> Filter_Items(String[] Brand, String[] Flavour,Float Price,String Size,String Type)


    ResultSet rs;
    List<Products> data = null;
    PreparedStatement stmt;
    try 
        StringBuilder param = new StringBuilder();
        if (Brand != null) 
            for (String str : Brand) 
                param.append("'").append(str).append("', ");
            
        
        StringBuilder param1 = new StringBuilder();
        if (Flavour != null) 
            for (String str : Flavour) 
                param1.append("'").append(str).append("', ");
            
        

        String prm = param.toString().length() > 2 ? param.toString()
                .substring(0, param.toString().length() - 2) : null;
        String prm1 = param1.toString().length() > 2 ? param1.toString()
                .substring(0, param1.toString().length() - 2) : null;

        String query = "select  * from products where ";

        if (prm != null && prm1 != null) 
            query += "Brand in (" + prm + ") and Flavour in (" + prm1 + ")";
         else if (prm != null && prm1 == null) 
            query += "Brand in (" + prm + ")";
         else if (prm1 != null && prm == null) 
            query += "Flavour in (" + prm1 + ")";
        

        stmt = DataBaseConnection.DBConn.getConnection().prepareStatement(query);
        rs = stmt.executeQuery();
        if (rs != null) 
            data = new ArrayList<Products>();
            while (rs.next()) 
                Products p = new Products();
                p.setTitle(rs.getString("Ttile"));
                p.setCategory(rs.getString("Category"));
                p.setSubCategory(rs.getString("SubCategory"));
                p.setSubCategoryTwo(rs.getString("SubCategorytwo"));
                p.setPrice(rs.getInt("Price"));
                p.setFlavour(rs.getString("Flavour"));
                p.setSize(rs.getString("Size"));
                p.setImage(rs.getString("image"));
                p.setBrand(rs.getString("Brand"));
                p.setInstock(rs.getString("instock"));
                p.setInstockQty(rs.getInt("instockqty"));
                data.add(p);
            
        
     catch (Exception e) 

        System.out.println(e.getStackTrace());

        return null;
    
    return data;





【问题讨论】:

注意:PreparedStatements 提供了一些防止 SQL 注入的保护,并且如果使用得当会获得一些性能提升。您没有正确使用它们(在 SQL 中嵌入未经处理的参数)。 好的,告诉我如何正确使用 仔细阅读我的评论。它解释了你做错了什么。顺便说一句...下次有人向您解释某些事情时,请尝试在发表“告诉我如何...”评论之前多考虑 1 分钟。 对不起,如果你介意的话。我没有这么说。我没有太多使用 SQL 的经验。 【参考方案1】:

您可以像往常一样使用第三方库进行验证,如 javax 验证或任何其他更专业的验证。 您可以使用所有 getter 和 setter 创建数据的 bean,并在 bean 上应用验证。

要传递数组,您需要像这样的 getter 和 setter:

public class Foo 
    private int[] array;

    public Foo(int[] array) 
        this.array = Arrays.copyOf(array, array.length);
    

    /** @param the array to use */
    public setArray(int[] array) 
        this.array = Arrays.copyOf(array, array.length);
    

    /** @return a copy of the array */
    public int[] getArray() 
        return Arrays.copyOf(array, array.length);
    

要验证 bean,请参阅 this 教程。

【讨论】:

实际上我正在传递一个数组如何生成传递数组的设置器 请问如何使用 bean 或 javax 应用验证 最后,我正在检查所有过滤器参数,例如类型大小价格等。就算是豆子【参考方案2】:

你真正需要的是根据它们的逻辑来命名变量。像prmprm1 这样的名字是没有意义的,而brandflavor 作为变量名更有意义,因为这就是其中的内容。

我不认为比较次数是个问题。但是给所有通用变量名,然后甚至不缩进 if 语句让我的眼睛呆滞。

这样的事情怎么样:

if (brand != null && flavor != null)  

    query += "Brand in (" + brand + ") and Flavour in (" + flavor + ")";
 
else if (brand != null && flavor == null) 

    query += "Brand in (" + brand + ")";
 
else if (flavor != null && brand == null) 

    query += "Flavour in (" + flavor + ")";

编辑:您可以做的一件事是将 SQL 拆分为两个变量,一个用于主查询,一个用于 where 子句,然后像这样添加到 where 子句:

private String addToWhereClause(String currentWhereClause, String fieldname, String value)

    String returnValue = "";
    if (value != null)
    
        if(!"".equals(currentWhereClause))
        
           returnValue += " AND ";
        
        returnValue += " "+fieldname+" IN(" + value + ") ";
    
    return returnValue;



String whereClause = "";
whereClause += addToWhereClause(whereClause, "Brand", brand);
whereClause += addToWhereClause(whereClause, "Flavour", flavor);
query = query + " " + whereClause;

【讨论】:

但是还有更多的比较,比如价格、尺寸、类型,我想要设计案例,比如品牌是否为空,其他不是,品牌风味为空,但其他不是,有什么办法可以避免这么多比较 用对你的目的有用的东西编辑了答案。

以上是关于避免从条件语句中进行比较的主要内容,如果未能解决你的问题,请参考以下文章

使用 CASE 语句比较 3 个条件并执行语句

条件判断语句比较

where条件放在子SQL语句中是否查询速度更快?

SQL 语句调优 where 条件 数据类型 临时表 索引

sql 语句,查询条件,两个字段拼接和一个串比较怎从实现呢?sql 语句怎么写!谢谢!

4. 第 4 章 条件选择