我想使用mybatis生成SQL以动态过滤查询和分组
我的SELECT语句是一个字符串,而我的WHERE过滤器是由GoodsExample.createCriteria()生成的。
当我仅使用一个String类型参数或一个GoodsExample实例作为参数时,此方法有效。 但是不能同时将两者作为mapper的方法参数传递。
我尝试了ANNOTATEDMAPPER模式和XMLMAPPER,并且产生的错误消息是相同的。
错误信息:
nested exception is org.apache.ibatis.binding.BindingException: Parameter 'oredCriteria' not found. Available parameters are [selectField, param1, example, param2]
GoodsController:
GoodsExample goodsExample = new GoodsExample();
GoodsExample.Criteria cri = goodsExample.createCriteria();
cri.andBrandIdIn(brandIdList);
String selectField = "brand, vendor";
return goodsMapper.dynamicalGroup(selectField, goodsExample);
GoodsMapper:
@SelectProvider(type = GoodsSqlProvider.class, method = "dynamicalGroup")
Page<Map> dynamicalGroup(
@Param("selectField") String selectField,
@Param("example") GoodsExample example
);
GoodsSqlProvider.java:
public String dynamicalGroup(Map<String,Object> map) {
String selectField = (String) map.get("selectField");
GoodsExample example = (GoodsExample) map.get("example");
SQL sql = new SQL();
sql.SELECT(selectField).FROM("goods").GROUP_BY(selectField);
applyWhere(sql, example, false);
return sql.toString();
}
如果我仅使用一个参数,就没有问题。 我在调试模式下进行了检查,无论是使用两个参数还是仅使用goodsExample,goodsExample在GoodsSqlProvider的断点调试中都显示了相同的内容。
applyWhere
方法,该方法由MyBatis生成器自动生成:
protected void applyWhere(SQL sql, GoodsExample example, boolean includeExamplePhrase) {
if (example == null) {
return;
}
String parmPhrase1;
String parmPhrase1_th;
String parmPhrase2;
String parmPhrase2_th;
String parmPhrase3;
String parmPhrase3_th;
if (includeExamplePhrase) {
parmPhrase1 = "%s #{example.oredCriteria[%d].allCriteria[%d].value}";
parmPhrase1_th = "%s #{example.oredCriteria[%d].allCriteria[%d].value,typeHandler=%s}";
parmPhrase2 = "%s #{example.oredCriteria[%d].allCriteria[%d].value} and #{example.oredCriteria[%d]" +
".criteria[%d].secondValue}";
parmPhrase2_th = "%s #{example.oredCriteria[%d].allCriteria[%d].value,typeHandler=%s} and #{example" +
".oredCriteria[%d].criteria[%d].secondValue,typeHandler=%s}";
parmPhrase3 = "#{example.oredCriteria[%d].allCriteria[%d].value[%d]}";
parmPhrase3_th = "#{example.oredCriteria[%d].allCriteria[%d].value[%d],typeHandler=%s}";
} else {
parmPhrase1 = "%s #{oredCriteria[%d].allCriteria[%d].value}";
parmPhrase1_th = "%s #{oredCriteria[%d].allCriteria[%d].value,typeHandler=%s}";
parmPhrase2 = "%s #{oredCriteria[%d].allCriteria[%d].value} and #{oredCriteria[%d].criteria[%d]" +
".secondValue}";
parmPhrase2_th = "%s #{oredCriteria[%d].allCriteria[%d].value,typeHandler=%s} and #{oredCriteria[%d]" +
".criteria[%d].secondValue,typeHandler=%s}";
parmPhrase3 = "#{oredCriteria[%d].allCriteria[%d].value[%d]}";
parmPhrase3_th = "#{oredCriteria[%d].allCriteria[%d].value[%d],typeHandler=%s}";
}
StringBuilder sb = new StringBuilder();
List<Criteria> oredCriteria = example.getOredCriteria();
boolean firstCriteria = true;
for (int i = 0; i < oredCriteria.size(); i++) {
Criteria criteria = oredCriteria.get(i);
if (criteria.isValid()) {
if (firstCriteria) {
firstCriteria = false;
} else {
sb.append(" or ");
}
sb.append('(');
List<Criterion> criterions = criteria.getAllCriteria();
boolean firstCriterion = true;
for (int j = 0; j < criterions.size(); j++) {
Criterion criterion = criterions.get(j);
if (firstCriterion) {
firstCriterion = false;
} else {
sb.append(" and ");
}
if (criterion.isNoValue()) {
sb.append(criterion.getCondition());
} else if (criterion.isSingleValue()) {
if (criterion.getTypeHandler() == null) {
sb.append(String.format(parmPhrase1, criterion.getCondition(), i, j));
} else {
sb.append(String.format(parmPhrase1_th, criterion.getCondition(), i, j,
criterion.getTypeHandler()));
}
} else if (criterion.isBetweenValue()) {
if (criterion.getTypeHandler() == null) {
sb.append(String.format(parmPhrase2, criterion.getCondition(), i, j, i, j));
} else {
sb.append(String.format(parmPhrase2_th, criterion.getCondition(), i, j,
criterion.getTypeHandler(), i, j, criterion.getTypeHandler()));
}
} else if (criterion.isListValue()) {
sb.append(criterion.getCondition());
sb.append(" (");
List<?> listItems = (List<?>) criterion.getValue();
boolean comma = false;
for (int k = 0; k < listItems.size(); k++) {
if (comma) {
sb.append(", ");
} else {
comma = true;
}
if (criterion.getTypeHandler() == null) {
sb.append(String.format(parmPhrase3, i, j, k));
} else {
sb.append(String.format(parmPhrase3_th, i, j, k, criterion.getTypeHandler()));
}
}
sb.append(')');
}
}
sb.append(')');
}
}
if (sb.length() > 0) {
sql.WHERE(sb.toString());
}
}