一. mybatisPlus与mongoDB条件构造器差异
- 先看示例
- mybatisplus条件构造器
list(Wrappers.lambdaQuery(OrderClass.class).select(OrderClass::getClassName).eq(!ObjectUtils.isEmpty(name),OrderClass::getClassName,name))
- mongoDb条件构造器
mongoTemplate.findOne(Query.query(Criteria.where("tacticsShopList").is(shopCode)), Map.class, "collectionName")
- 痛点
- mondoDb的条件构造器没有非空判断条件参数,如果需要判断非空只能写另写判断
- mondoDb的条件构造器的字段只能写字符串, 不能用Lambda表达式写
二. 自定义mongoDB条件构造器
针对上述痛点自定义mongoDB条件构造器
2.1 自定义函数接口
@FunctionalInterface
public interface SFunction<T, R> extends Function<T, R>, Serializable {
}
2.2 条件构造器
只写了部分条件,更多条件方法自己实现
public class CriteriaVo extends Criteria{
public static CriteriaVo create(){
return new CriteriaVo();
}
/**
* 模糊匹配
* @param fun
* @param value
* @return
*/
public <T> CriteriaVo regexN (SFunction<T,?> fun, String value){
if(!ObjectUtils.isEmpty(value)){
this.and(columnToString(fun)).regex(".*"+value)+".*");
}
return this;
}
/**
* 精确匹配
* @param fun
* @param value
* @return
*/
public <T> CriteriaVo isN (SFunction<T,Object> fun,Object value){
if(!ObjectUtils.isEmpty(value)){
this.and(columnToString(fun)).is(value);
}
return this;
}
/**
* 大于
* @param fun
* @param value
* @param <T>
* @return
*/
public <T> CriteriaVo gteN (SFunction<T,Object> fun,Object value){
if(!ObjectUtils.isEmpty(value)){
this.and(columnToString(fun)).gte(value);
}
return this;
}
/**
* 小于
* @param fun
* @param value
* @param <T>
* @return
*/
public <T> CriteriaVo lteN (SFunction<T,Object> fun,Object value){
if(!ObjectUtils.isEmpty(value)){
this.and(columnToString(fun)).lte(value);
}
return this;
}
public <T,R> CriteriaVo elemMatchN (SFunction<T,Object> fun1, SFunction<R,Object> fun2, Object value){
if(!ObjectUtils.isEmpty(value)){
this.and(columnToString(fun1)).elemMatch(Criteria.where(columnToString(fun2)).is(value));
}
return this;
}
public static <T> String columnToString(SFunction<T, ?> func) {
String fieldName = "";
try {
Method writeReplace = func.getClass().getDeclaredMethod("writeReplace");
writeReplace.setAccessible(Boolean.TRUE);
SerializedLambda serializedLambda = (SerializedLambda) writeReplace.invoke(func);
String methodName = serializedLambda.getImplMethodName();
if(methodName.startsWith("get") || methodName.startsWith("set")){
fieldName = methodName.substring(3);
}else {
fieldName = methodName;
}
fieldName = Introspector.decapitalize(fieldName);
} catch (Exception e) {
e.printStackTrace();
}
return fieldName;
}
}
2.3 使用示例
List<Map> maps = mongoTemplate.find(Query.query(CriteriaVo.create().isN(User::getNick, "name")), Map.class, "collectionName");
网友评论