目錄
場景
撥打頻次,前端不篩選時,傳參:"",需要過濾出0的情況時,傳參:0;但過濾0的情況時,還是出現了全量數據。
代碼:
<if test="data.callFrequency != null and data.callFrequency != ''">
...
</if>
查看mybatis執行代碼
class ASTNotEq extends ComparisonExpression {
public ASTNotEq(int id) {
super(id);
}
public ASTNotEq(OgnlParser p, int id) {
super(p, id);
}
protected Object getValueBody(OgnlContext context, Object source) throws OgnlException {
//傳參值,也就是0
Object v1 = this._children[0].getValue(context, source);
//test中條件的值,也就是''
Object v2 = this._children[1].getValue(context, source);
// 去比較兩值
return OgnlOps.equal(v1, v2) ? Boolean.FALSE : Boolean.TRUE;
}
}
獲取到v1 = 0,v2 = '' 去比較
查看比較邏輯
public static boolean equal(Object v1, Object v2) {
if (v1 == null) {
return v2 == null;
// 走到isEqual方法
} else if (v1 != v2 && !isEqual(v1, v2)) {
if (v1 instanceof Number && v2 instanceof Number) {
return ((Number)v1).doubleValue() == ((Number)v2).doubleValue();
} else {
return false;
}
} else {
return true;
}
}
public static boolean isEqual(Object object1, Object object2) {
boolean result = false;
if (object1 == object2) {
result = true;
} else if (object1 != null && object1.getClass().isArray()) {
if (object2 != null && object2.getClass().isArray() && object2.getClass() == object1.getClass()) {
result = Array.getLength(object1) == Array.getLength(object2);
if (result) {
int i = 0;
for(int icount = Array.getLength(object1); result && i < icount; ++i) {
result = isEqual(Array.get(object1, i), Array.get(object2, i));
}
}
}
} else {
// 進入到compareWithConversion方法
result = object1 != null && object2 != null && (object1.equals(object2) || compareWithConversion(object1, object2) == 0);
}
return result;
}
public static int compareWithConversion(Object v1, Object v2) {
int result;
if (v1 == v2) {
result = 0;
} else {
// 獲取到v1,v2類型的對應值
int t1 = getNumericType(v1); // 4
int t2 = getNumericType(v2); // 10
int type = getNumericType(t1, t2, true);// 10
switch(type) {
case 6:
result = bigIntValue(v1).compareTo(bigIntValue(v2));
break;
case 9:
result = bigDecValue(v1).compareTo(bigDecValue(v2));
break;
case 10:
// t1 != t2
if (t1 == 10 && t2 == 10) {
if (v1 instanceof Comparable && v1.getClass().isAssignableFrom(v2.getClass())) {
result = ((Comparable)v1).compareTo(v2);
break;
}
throw new IllegalArgumentException("invalid comparison: " + v1.getClass().getName() + " and " + v2.getClass().getName());
}
case 7:
case 8:
// 走到這,兩個數都被強轉double 0.0
double dv1 = doubleValue(v1);
double dv2 = doubleValue(v2);
// 返回true,'' == 0
return dv1 == dv2 ? 0 : (dv1 < dv2 ? -1 : 1);
default:
long lv1 = longValue(v1);
long lv2 = longValue(v2);
return lv1 == lv2 ? 0 : (lv1 < lv2 ? -1 : 1);
}
}
return result;
}
public static int getNumericType(Object value) {
if (value != null) {
Class c = value.getClass();
if (c == Integer.class) {
return 4;
}
if (c == Double.class) {
return 8;
}
if (c == Boolean.class) {
return 0;
}
if (c == Byte.class) {
return 1;
}
if (c == Character.class) {
return 2;
}
if (c == Short.class) {
return 3;
}
if (c == Long.class) {
return 5;
}
if (c == Float.class) {
return 7;
}
if (c == BigInteger.class) {
return 6;
}
if (c == BigDecimal.class) {
return 9;
}
}
return 10;
}
getNumericType獲取到v1,v2的類型對應值,如下圖
通過getNumericType(t1, t2, true)方法獲取type
public static int getNumericType(int t1, int t2, boolean canBeNonNumeric) {
if (t1 == t2) {
return t1;
} else if (canBeNonNumeric && (t1 == 10 || t2 == 10 || t1 == 2 || t2 == 2)) {
// v2 = 10, 返回10
return 10;
} else {
if (t1 == 10) {
t1 = 8;
}
if (t2 == 10) {
t2 = 8;
}
if (t1 >= 7) {
if (t2 >= 7) {
return Math.max(t1, t2);
} else if (t2 < 4) {
return t1;
} else {
return t2 == 6 ? 9 : Math.max(8, t1);
}
} else if (t2 >= 7) {
if (t1 < 4) {
return t2;
} else {
return t1 == 6 ? 9 : Math.max(8, t2);
}
} else {
return Math.max(t1, t2);
}
}
}
由於v1 != v2,所以跳到case 8,如下,返回true
最終,返回true,傳參爲0被條件 data.callFrequency != '' 過濾掉,所以不會走撥打頻次篩選。
修改
修改test篩選如下:
<if test="data.callFrequency != null and data.callFrequency != '' or data.callFrequency == 0">
...
</if>