Java使用Criteria实现多条件查询

本文介绍了一种使用Java对MongoDB进行多条件筛选的方法,通过前端传入多个查询条件,后端遍历生成CriteriaList,支持等于、小于、大于等操作,并提供了自定义查询帮助类实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:

前端传入多个查询条件,根据查询条件、查询字段和值使用Java对MongoDB进行多条件筛选。

实现方法:

查询条件传入List<JSONObject>,格式如下:

[
    {
        "condition": "is",
        "key":"name"
        "value": "xxxxxx"
    },
    {
        "condition": "gte",
        "key":"age"
        "value": 18
    }
]

后端进行遍历:

// 最终生成的 CriteriaList
ArrayList<Criteria> arrayList = new ArrayList<>();
// Criteria 对象
Criteria criteria;
// 每遍历一次,list添加一个查询条件
criteria = Criteria.where(object.getString(KEY)).is(object.getString(VALUE));
arrayList.add(criteria);

自定义查询帮助类:

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.bson.Document;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.*;
import java.util.regex.Pattern;

/**
 * 自定义查询帮助类
 *
 * @author xkk
 * create Date: 2019/11
 */
public class MongoUtil {

    /**
     * 等于
     */
    private static final String IS = "is";

    /**
     * 小于
     */
    private static final String LT = "lt";

    /**
     * 小于等于
     */
    private static final String LTE = "lte";

    /**
     * 大于
     */
    private static final String GT = "gt";

    /**
     * 大于等于
     */
    private static final String GTE = "gte";

    /**
     * in
     */
    private static final String IN = "in";

    /**
     * not in
     */
    private static final String NIN = "nin";

    /**
     * 并且
     */
    private static final String AND = "and";

    /**
     * 不等于
     */
    private static final String NE = "ne";

    /**
     * 数字不等于
     */
    private static final String NUM_NE = "num_ne";

    /**
     * 数组不等于
     */
    private static final String ARR_NE = "arr_ne";

    /**
     * all
     */
    private static final String ALL = "all";

    /**
     * all
     */
    private static final String LIKE = "like";

    /**
     * all
     */
    private static final String NUM_IS = "num";

    /**
     * key
     */
    private static final String KEY = "key";

    /**
     * value
     */
    private static final String VALUE = "value";

    /**
     * 正序
     */
    private static final String ASC = "asc";

    /**
     * 倒序
     */
    private static final String DESC = "desc";

    /**
     * 添加查询条件,生成ArrayList<Criteria>
     *
     * @param conditionList 条件列表
     * @return
     */
    private static Criteria[] genCriteria(List<JSONObject> conditionList) {

        ArrayList<Criteria> arrayList = new ArrayList<>();

        conditionList.forEach(object -> {
            Criteria criteria;
            // 查询条件
            String condition = object.getString("condition");
            if (StringUtils.isBlank(condition)) {
                return;
            }
            if (ObjectUtils.isEmpty(object.get(VALUE))) {
                return;
            }
            // 查询条件可根据需求进行扩展
            switch (condition) {
                case IS: {
                    criteria = Criteria.where(object.getString(KEY)).is(object.getString(VALUE));
                    arrayList.add(criteria);
                    break;
                }
                case LT: {
                    criteria = Criteria.where(object.getString(KEY)).lt(object.getInteger(VALUE));
                    arrayList.add(criteria);
                    break;
                }
                case LTE: {
                    criteria = Criteria.where(object.getString(KEY)).lte(object.getInteger(VALUE));
                    arrayList.add(criteria);
                    break;
                }
                case GT: {
                    criteria = Criteria.where(object.getString(KEY)).gt(object.getInteger(VALUE));
                    arrayList.add(criteria);
                    break;
                }
                case GTE: {
                    criteria = Criteria.where(object.getString(KEY)).gte(object.getInteger(VALUE));
                    arrayList.add(criteria);
                    break;
                }
                case IN: {
                    criteria = Criteria.where(object.getString(KEY)).in(object.getString(VALUE));
                    arrayList.add(criteria);
                    break;
                }
                case NIN: {
                    criteria = Criteria.where(object.getString(KEY)).nin(object.getString(VALUE));
                    arrayList.add(criteria);
                    break;
                }
                case AND: {
                    criteria = Criteria.where(object.getString(KEY)).and(object.getString(VALUE));
                    arrayList.add(criteria);
                    break;
                }
                case NUM_NE: {
                    criteria = Criteria.where(object.getString(KEY)).ne(object.getInteger(VALUE));
                    arrayList.add(criteria);
                    break;
                }
                case NE: {
                    criteria = Criteria.where(object.getString(KEY)).ne(object.get(VALUE));
                    arrayList.add(criteria);
                    break;
                }
                case ARR_NE: {
                    criteria = Criteria.where(object.getString(KEY)).ne(object.get(VALUE));
                    criteria = Criteria.where(object.getString(KEY)).elemMatch(criteria);
                    arrayList.add(criteria);
                    break;
                }
                case ALL: {
                    criteria = Criteria.where(object.getString(KEY)).all(object.getJSONArray(VALUE).toArray());
                    arrayList.add(criteria);
                    break;
                }
                case LIKE: {
                    Pattern pattern = Pattern.compile("^.*" + object.getString(VALUE) + ".*$", Pattern.CASE_INSENSITIVE);
                    criteria = Criteria.where(object.getString(KEY)).regex(pattern);
                    arrayList.add(criteria);
                    break;
                }
                case NUM_IS: {
                    criteria = Criteria.where(object.getString(KEY)).is(object.getInteger(VALUE));
                    arrayList.add(criteria);
                    break;
                }
                default: {
                    criteria = Criteria.where("1").is("1");
                    arrayList.add(criteria);
                    break;
                }
            }
        });
        Criteria[] criteria = new Criteria[arrayList.size()];
        arrayList.toArray(criteria);
        return criteria;
    }

    /**
     * 生成query
     *
     * @param object object
     * @param flag   条件:true 并且,false 或者
     * @return
     */
    private static Query getQuery(JSONObject object, boolean flag) {
        Query query = new Query();
        // 转为标准json格式
        // 是否有条件集合的键
        boolean b = object.containsKey("conditionList");
       
        if (b) {
            // 存在则获取
            // 条件集合
        List<JSONObject> conditionList = object.getJSONArray("conditionList").toJavaList(JSONObject.class);
            // 是否有值
            if (conditionList.size() > 0) {
                // 生成 Criteria 数组
                Criteria[] criteria = genCriteria(conditionList);
                // 条件 & or |
                if (flag) {
                    query.addCriteria(new Criteria().andOperator(criteria));
                } else {
                    query.addCriteria(new Criteria().orOperator(criteria));
                }
            }
        }
        // 是否存在排序字段
        boolean bsf = object.containsKey("sortField");
        // 是否存在排序类型
        boolean bst = object.containsKey("sortType");
        String sortField = "";
        String sortType = "";
        if (bsf && bst) {
            // 存在则获取
            sortField = object.getString("sortField");
            sortType = object.getString("sortType");
            // 字段判空
            if (StringUtils.isNotBlank(sortField) && StringUtils.isNotBlank(sortType)) {
                // 正序/倒序
                if (ASC.equals(sortType)) {
                    query.with(Sort.by(Sort.Order.asc(sortField)));
                } else {
                    query.with(Sort.by(Sort.Order.desc(sortField)));
                }
            }
        }
        return query;
    }

    /**
     * 条件并且
     * 最终在外部调用此方法
     *
     * @param object
     * @return
     */
    public static Query genQueryAnd(JSONObject object) {
        return getQuery(object, true);
    }

    /**
     * 条件OR
     * 最终在外部调用此方法
     * 或者查询:相当于MySQL的OR查询条件
     *
     * @param object
     * @return
     */
    public static Query genQueryOr(JSONObject object) {
        return getQuery(object, false);
    }
}

 

以下是使用光流法进行二值化图像识别的 Python 代码: ```python import cv2 cap = cv2.VideoCapture(0) # 打开摄像头 _, frame1 = cap.read() # 读取第一帧 frame1_gray = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY) # 转为灰度图像 # 设置参数 lk_params = dict(winSize=(15, 15), maxLevel=4, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)) while True: _, frame2 = cap.read() # 读取当前帧 frame2_gray = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY) # 转为灰度图像 # 计算光流 flow = cv2.calcOpticalFlowFarneback(frame1_gray, frame2_gray, None, 0.5, 3, 15, 3, 5, 1.2, 0) magnitude, angle = cv2.cartToPolar(flow[...,0], flow[...,1]) # 二值化图像识别 threshold = 10 # 阈值 mask = cv2.threshold(magnitude, threshold, 255, cv2.THRESH_BINARY)[1] # 二值化 contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 查找轮廓 for contour in contours: area = cv2.contourArea(contour) if area > 100: # 过滤面积小于 100 的轮廓 cv2.drawContours(frame2, [contour], -1, (0, 255, 0), 2) # 绘制矩形 cv2.imshow('frame', frame2) # 显示图像 # 更新帧 frame1_gray = frame2_gray.copy() if cv2.waitKey(1) & 0xFF == ord('q'): # 按下 'q' 键退出循环 break cap.release() # 释放摄像头 cv2.destroyAllWindows() # 关闭所有窗口 ``` 代码中的 `calcOpticalFlowFarneback` 函数用于计算光流,`threshold` 变量为阈值,`cv2.threshold` 函数用于将灰度图像二值化,`cv2.findContours` 函数用于查找轮廓,`cv2.drawContours` 函数用于绘制矩形。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值