2

我需要一些帮助来设计我的问题的逻辑。

模型豆

package com.ashish.model;
public class Model {
    public Integer a,b,c,d;
    public String f,g,h,i,j;
}

服务等级

package com.ashish.service;

import com.ashish.model.Model;
public class Service {
    public StringBuilder query = null;  
    public Service(){
        query = new StringBuilder("Select * from A where ");
    }
    public String build(Model m){
            if(m.a != null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
        query.append("a="+m.a);
    if(m.a == null&&m.b!=null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
        query.append("b="+m.b);
    if(m.a == null&&m.b==null&&m.c!=null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
        query.append("c="+m.c);
    if(m.a == null&&m.b==null&&m.c==null&&m.d!=null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
        query.append("d="+m.d);
    if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e!=null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
        query.append("e="+m.e);
    if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f!=null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
        query.append("f="+m.f);
    if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g!=null&&m.h==null&&m.i==null&&m.j==null)
        query.append("g="+m.g);
    if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h!=null&&m.i==null&&m.j==null)
        query.append("h="+m.h);
    if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i!=null&&m.j==null)
        query.append("i="+m.i);
    if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j!=null)
        query.append("j="+m.j);
    if(m.a != null&&m.b!=null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
        query.append("a="+m.a);query.append(" b="+m.b);
    if(m.a != null&&m.b==null&&m.c!=null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
        query.append("a="+m.a);query.append(" c="+m.c);
    if(m.a != null&&m.b==null&&m.c==null&&m.d!=null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
        query.append("a="+m.a);query.append(" d="+m.d);
    // ... 512 lines in this pattern
    return query.toString();

        return query.toString();
    }
}

我想这样写public String build(Model m),这样我就不必写 512 if-else 条件。

条件:

  1. Model 类的所有实例变量都可以有两个值(null,not null)

  2. 它们都可以为空,或者它们都可以不为空。

  3. 总共有 512 种组合(因为每个实例变量都有两个状态,并且有 9 个实例变量,所以条件总数为 2^9)

  4. 实例变量的顺序无关紧要。

  5. 我的项目使用 Java 6,所以我不能在 String 上使用 switch。

我研究了各种模式,但没有一个符合我的要求。

感谢您的关注

4

6 回答 6

3

如下的私有辅助方法应该做到这一点 -

private void appendIfNotNull(String fieldOp, String val) {
    if(val != null) {
        query.append(fieldOp).append(val);
    }
}

然后只需在build方法中调用它 -

public String build(Model m) {
    appendIfNotNull("a=", m.a); //no null check, just need to repeat this for all fields
于 2013-10-24T18:28:46.453 回答
1

也许您想尝试使用Java 反射来读取模型的所有字段并读取它们。您无需知道字段名称即可阅读。因此,即使您扩展了 Model 类,它也将是完全动态的和通用的。

    Class modelClass = Class.forName(Model.class.getName());
    Field[] fields = circleClass.getFields(); //includes all fields declared in you model class
    for (Field f : fields) {
        System.out.println("field " + f.getName() + " has value: " + f.get(<YOUR_MODEL_INSTANCE>));
    }

示例代码改编自: - http://forgetfulprogrammer.wordpress.com/2011/06/13/java-reflection-class-getfields-and-class-getdeclaredfields/

于 2013-10-24T18:31:10.087 回答
1

这段代码有意义吗?

interface ToStringer {
    void appendTo(StringBuilder sb);
}

class NullToStringer implements ToStringer {
    public void appendTo(StringBuilder sb) {
        // Do nothing
    }
}

class IntegerToStringer implements ToStringer {
    private String fieldName;
    private Integer val;
    public IntegerToStringer(String fieldName, Integer val) {
        this.fieldName = fieldName;
        this.val = val;
    }


    public void appendTo(StringBuilder sb) {
        sb.append(field).append(" = ").append(val);
    }
}

public class ToStringFactory {
    public ToStringer getToStringer(String fieldName, Integer val) {
        if (val == null) {
            return new NullToStringer();
        } else {
            return new IntegerToStringer(fieldName, val);
        }
    }       

    public ToStringer getToStringer(String fieldName, String val) {
        ...
    }
}

public String build(Model m){
    ArrayList<ToStringInstance> list = ...;
    list.add(ToStringFactory.getToStringer("f", m.f));
    list.add(ToStringFactory.getToStringer("g", m.g));
    list.add(ToStringFactory.getToStringer("h", m.h));

    StringBuilder sb = ...;

    for (ToStringInstance tsi : list) {
       tsi.appendTo(sb);
    }

    return sb.toString();

}

我不确定您要实现什么逻辑,但一般方法:创建接口、打印值的具体实现、使用 NullValue 模式隐藏空问题以及使用工厂控制对象创建应该可以解决问题。

通过使用这种方法,您可以通过避免多个 if-else 语句来避免 2^9 组合的问题。

更新。刚想到我。您可以使用反射。遍历所有字段,获取每个字段的值,如果不为空则打印。也许这就足够了。

于 2013-10-24T18:34:18.903 回答
1

似乎您想为每个不是的元素附加到查询中null。这可以通过一两个辅助方法非常简单地完成:

public class Service {
    public StringBuilder query = null;  
    public Service(){
        query = new StringBuilder("Select * from A where ");
    }
    public String build(Model m) {
        boolean added = first;
        first &= !maybeAdd("a", m.a, first);
        first &= !maybeAdd("b", m.b, first);
        . . . // all the rest of the fields of m
    }

    /**
     * Add an equality test to an SQL query if the value is not {@code null}.
     * @param key the field name for the query
     * @param value the value to test for equality
     * @param first flag indicating that no conditions have been added
     * @return {@code true} if the value was appended; {@code false} otherwise.
     */    
    private boolean maybeAdd(String key, Object value, boolean first) {
        if (value != null) {
            if (!first) {
                query.append(" AND ");
            }
            query.append(key).append('=').append(value);
            return true;
        }
        return false;
    }
}

请注意,如果模型的所有字段都是null,您的查询将不会正确形成。您可能希望在maybeAdd方法中包含适当的逻辑来弥补这一点。

于 2013-10-24T18:51:21.397 回答
1

正如我在评论中提到的那样if,每个组合都不需要不同。您只需要附加不为空的值,并忽略那些为空的值。让我知道这是否适合您。

public String build(Model m) {
    // use this to know when to add " AND " to separate existing values
    boolean appended = false;

    if (m.a != null) {
        query.append("a=" + m.a);
        appended = true;
    }
    if (m.b != null) {
        if (appended) {
            query.append(" AND ");
        }
        query.append("b=" + m.b);
        appended = true;
    }
    if (m.c != null) {
        if (appended) {
            query.append(" AND ");
        }
        query.append("c=" + m.c);
        appended = true;
    }
    if (m.d != null) {
        if (appended) {
            query.append(" AND ");
        }
        query.append("d=" + m.d);
        appended = true;
    }
    if (m.e != null) {
        if (appended) {
            query.append(" AND ");
        }
        query.append("e=" + m.e);
        appended = true;
    }
    if (m.f != null) {
        if (appended) {
            query.append(" AND ");
        }
        query.append("f=" + m.f);
        appended = true;
    }
    if (m.g != null) {
        if (appended) {
            query.append(" AND ");
        }
        query.append("g=" + m.g);
        appended = true;
    }
    if (m.h != null) {
        if (appended) {
            query.append(" AND ");
        }
        query.append("h=" + m.h);
        appended = true;
    }
    if (m.i != null) {
        if (appended) {
            query.append(" AND ");
        }
        query.append("i=" + m.i);
        appended = true;
    }
    if (m.j != null) {
        if (appended) {
            query.append(" AND ");
        }
        query.append("j=" + m.j);
        appended = true;
    }
    return query.toString();
}
于 2013-10-24T18:47:03.600 回答
0

我不知道为什么你需要两个 if 语句:

if( m.a == null) { 
  query.append("m=null");
} else { 
 query.append("m="+m.a);
}
if( m.b == null) { 
  query.append("m=null");
} else { 
 query.append("m="+m.b);
}
于 2013-10-24T18:44:55.570 回答