最近时间多,于是开始学习java. 目前就关于mbp在多条件搜索的情况下的一些优化思路做一个分享,
先说明需求:
如上图的表格中所示该table有多个列,假设每个列都支持搜索,在springboot中用到实体类Employee接收,在一般情况下
代码就会这样:
目前只是伪代码还没加入非空判断,假设搜索项有十几二十个就要手写十几个"eq","like","in"并且还要做非空判断这样的代码十分不优雅,所以mbp提供了一套比较简洁的查询方式. 如图所示:
在加入这个注解之后name字段的搜索sql就会以like的条件进行搜索, 然后再service层直接在queryWrapper中传入对应的实体类:
这样就可以实现非常简洁的多条件搜索 但是问题来了,目前的SQLCondition中官方给的常量只有以下六个:
官方说是可以自定义,然后我就自定义了in查询 字符串应该是 "%s in (#{%s})",但是搜索出来的条件并不正确,我在想应该是sql直接把括号中的内容当成字符串了无法解析,所以如果无法用注解实现in查询(这个待大佬解答,我也不清楚为啥),这个关于queryWrapper传参的用法就很鸡肋,所以打算自己实现一套比较简洁的查询方式,顺便也了解一下java注解的原理. 首先创建一个自定义注解:
默认值为eq 可以传入 like 或 in 使用方式:
然后创建一个SeachConditionUtils
public class SearchConditionUtils<T> {
private T entity;
private QueryWrapper queryWrapper;
private Class c;
public SearchConditionUtils(T entity, QueryWrapper queryWrapper){
this.entity = entity;
this.queryWrapper = queryWrapper;
this.c = entity.getClass();
Field[] fields = this.c.getDeclaredFields();
for(Field field : fields){
String fieldName = field.getName();
String fieldValue = getFieldValue(fieldName);
String conditionType = getAnnotation(field);
linkCondition(fieldName,fieldValue,conditionType);
}
}
public void linkCondition(String fieldName,String fieldValue,String conditionType){
if(conditionType.equals("eq")){
if(hasFieldValue(fieldValue)){
queryWrapper.eq(fieldName,fieldValue);
}
}
if(conditionType.equals("like")){
if(hasFieldValue(fieldValue)){
queryWrapper.like(fieldName,fieldValue);
}
}
if(conditionType.equals("in")){
if(hasFieldValue(fieldValue)){
queryWrapper.in(fieldName,fieldValue.split(","));
}
}
}
// public void linkEqCondition(String fieldName,String fieldValue){
//
// }
// public void linkLikeCondition(String fieldName,String fieldValue){
//
// }
// public void linkInCondition(String fieldName,String fieldValue){
//
// }
public Boolean hasFieldValue(String fieldValue){
return fieldValue != null && !fieldValue.equals("");
}
public String getFieldValue(String fieldName){
String methodName = getMethodName(fieldName);
String value = "";
try {
Method method = c.getDeclaredMethod(methodName,null);
value =(String) method.invoke(entity,null);
}catch (Exception e){
System.out.println(e);
}
return value;
}
public String getAnnotation(Field field){
String value = "eq";
CustomAnnotation customAnnotation = field.getAnnotation(CustomAnnotation.class);
if(customAnnotation !=null){
value = customAnnotation.value();
}
return value;
}
public String getMethodName(String fieldName){
return "get" + fieldName.substring(0,1).toUpperCase()+ fieldName.substring(1);
}
}
在service中直接创建searchCondtionUtils实例传入employee 和 queryWrapper 就可以实现对queryWrapper的优雅查询,不需要写大量的if不需要写大量的条件判断。 刚学java不懂以上的解决方式是否最优,待大佬点评。