# 由BigDecimal类型的数据引出的问题分析

### 由BigDecimal类型的数据引出的问题分析

    public static void main(String[] args) {
BigDecimal decimal1 = BigDecimal.valueOf(0);
BigDecimal decimal2 = new BigDecimal("0.00");
System.out.println("the result is " +decimal1.equals(decimal2));
}

the result is false

BigDecimal类的equals方法源码如下：

    public boolean equals(Object x) {
if (!(x instanceof BigDecimal))
return false;
BigDecimal xDec = (BigDecimal) x;
if (x == this)
return true;
if (scale != xDec.scale)//这里会比较数字的精度
return false;
long s = this.intCompact;
long xs = xDec.intCompact;
if (s != INFLATED) {
if (xs == INFLATED)
xs = compactValFor(xDec.intVal);
return xs == s;
} else if (xs != INFLATED)
return xs == compactValFor(this.intVal);

return this.inflate().equals(xDec.inflate());
}

    public static void main(String[] args) {
BigDecimal decimal1 = BigDecimal.valueOf(0).setScale(2);
BigDecimal decimal2 = new BigDecimal("0.00").setScale(2);
System.out.println("the result is " +decimal1.equals(decimal2));
}

the result is true

    public static void main(String[] args) {
BigDecimal decimal1 = BigDecimal.valueOf(1.1);
BigDecimal decimal2 = new BigDecimal("1.10");
System.out.println("the result is " +decimal1.compareTo(decimal2));
}

the result is 0

0表示两个数相等，所有可以通过compareTo实现不同精度的两个BigDecimal类型的数字是否相等的比较

<select id="selectByCondition" resultType="com.scove.demo.domain.Score">
select * from tb_score where 1=1
<if test="score!=null and score!=0">
and score&gt;#{score}
</if>
...

score是一个BigDecimal类型的字段，score!=0 Mybatis是如何进行判断的，会不会用的是上面的equals方法？如果是那么项目上线会不会捅大篓子，想到这儿，有点怕了。写了个程序测了下，这样写完全没问题，能够达到我想要的目的。但是还是有点担心，看看Mybatis底层是如何实现的吧，以免以后犯类似的错误嘛。

public class ExpressionEvaluator {

public boolean evaluateBoolean(String expression, Object parameterObject) {
Object value = OgnlCache.getValue(expression, parameterObject);
if (value instanceof Boolean) {
return (Boolean) value;
}
if (value instanceof Number) {
return !new BigDecimal(String.valueOf(value)).equals(BigDecimal.ZERO);
}
return value != null;
}
...
public final class OgnlCache {

....
public static Object getValue(String expression, Object root) {
try {
Map<Object, OgnlClassResolver> context = Ognl.createDefaultContext(root, new OgnlClassResolver());
return Ognl.getValue(parseExpression(expression), context, root);
} catch (OgnlException e) {
throw new BuilderException("Error evaluating expression '" + expression + "'. Cause: " + e, e);
}
}

    public static void main(String[] args) {
ExpressionEvaluator evaluator = new ExpressionEvaluator();
String expression = "score!=null and score!=0";
DynamicContext context = new DynamicContext(new Configuration(), null);
context.bind("score", BigDecimal.valueOf(0.1));
Boolean flag = evaluator.evaluateBoolean(expression , context.getBindings());
System.out.println("the result is " +flag);
}

the result is true
##### 总结

posted @ 2018-08-19 11:55  lensar  阅读(...)  评论(...编辑  收藏