首页 > 数据库 >Mongodb数据库基于spring-boot-starter-data-mongodb的查询工具

Mongodb数据库基于spring-boot-starter-data-mongodb的查询工具

时间:2023-08-25 15:33:33浏览次数:33  
标签:return String val Mongodb criteria boot field mongodb import

/**
 * 字段注解
 */
public @interface BuilderField {
    /**
     * 对应的数据库字段名称
     * @return
     */
    String name();
}
import lombok.SneakyThrows;

import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import java.util.function.Function;

@FunctionalInterface
public interface BuilderFunction<T, R> extends Function<T, R>, Serializable {
    @SneakyThrows
    default String getFieldName() {
        String methodName = getMethodName();
        if (methodName.startsWith("get")) {
            methodName = methodName.substring(3);
        }
        return methodName;
    }

    @SneakyThrows
    default String getMethodName() {
        return getSerializedLambda().getImplMethodName();
    }

    @SneakyThrows
    default Class<?> getFieldClass() {
        return getReturnType();
    }

    @SneakyThrows
    default SerializedLambda getSerializedLambda() {
        Method method = getClass().getDeclaredMethod("writeReplace");
        method.setAccessible(true);
        return (SerializedLambda) method.invoke(this);
    }

    @SneakyThrows
    default Class<?> getReturnType() {
        SerializedLambda lambda = getSerializedLambda();
        Class<?> className = Class.forName(lambda.getImplClass().replace("/", "."));
        Method method = className.getMethod(getMethodName());
        return method.getReturnType();
    }
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.beans.Introspector;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description : 查询封装
 * @Author : cxw
 * @Date : 2023/8/7 13:13
 * @Version : 1.0
 **/
public class BuilderQuery<T>  {

    private static Pattern humpPattern = Pattern.compile("[A-Z]");

    private static final Pattern GET_PATTERN = Pattern.compile("^get[A-Z].*");
    private static final Pattern IS_PATTERN = Pattern.compile("^is[A-Z].*");

    private static Logger logger = LoggerFactory.getLogger(BuilderQuery.class);

    private Field[] fields;

    private String className;

    private Class _clazz;


    Criteria criteria =null;

    public BuilderQuery(Class<?> clazz) {
        fields = clazz.getDeclaredFields();
        className=clazz.getName();
        _clazz=clazz;
    }

    /**
     * 精准匹配 field=val 的sql
     * @param func 类的字段名get方法
     * @param val 类对应的字段值
     * @return
     */
    public BuilderQuery eq(BuilderFunction<T, Object> func,Object val) throws Exception {
        String field = getFieldName(func.getMethodName());
        String _field = getSQLField(field);
        if(criteria==null){
            criteria=Criteria.where(_field).is(val);
        }else {
            criteria.and(_field).is(val);
        }
        return this;
    }

    /**
     * in 查询
     * @param func 类的字段名get方法
     * @param val 类对应的字段值
     * @return
     */
    public BuilderQuery in(BuilderFunction<T, Object> func, List<Object> val) throws Exception {
        String field = getFieldName(func.getMethodName());
        String _field = getSQLField(field);
        if(criteria==null){
            criteria=Criteria.where(_field).in(val);
        }else {
            criteria.and(_field).in(val);
        }
        return this;
    }

    /**
     * like模糊 查询
     * @param func 类的字段名get方法
     * @param val 类对应的字段值
     * @return
     */
    public BuilderQuery like(BuilderFunction<T, Object> func, String val,Boolean allLike) throws Exception {
        String field = getFieldName(func.getMethodName());
        String _field = getSQLField(field);
        if(criteria==null){
            criteria=Criteria.where(_field).regex(val);
        }else {
            criteria.and(_field).regex(val);
        }
        return this;
    }

    /**
     * 大于查询
     * @param func 类的字段名get方法
     * @param val 类对应的字段值
     * @return
     */
    public BuilderQuery gt(BuilderFunction<T, Object> func, String val) throws Exception {
        String field = getFieldName(func.getMethodName());
        String _field = getSQLField(field);
        if(criteria==null){
            criteria=Criteria.where(_field).gt(val);
        }else {
            criteria.and(_field).gt(val);
        }
        return this;
    }

    /**
     * 小于查询
     * @param func 类的字段名get方法
     * @param val 类对应的字段值
     * @return
     */
    public BuilderQuery lt(BuilderFunction<T, Object> func, String val) throws Exception {
        String field = getFieldName(func.getMethodName());
        String _field = getSQLField(field);
        if(criteria==null){
            criteria=Criteria.where(_field).lt(val);
        }else {
            criteria.and(_field).lt(val);
        }
        return this;
    }


    /**
     * 生成字段
     * @param field
     * @return
     * @throws Exception
     */
    private String getSQLField(String field) throws Exception {
        for (Field field1 : fields) {
            if(field1.getName().equals(field)){
                // 获取字段上的注解对象
                Annotation[] annotations =field1.getDeclaredAnnotations();
                String tableField = hasBuilderField(annotations);
                if(tableField==null)tableField=humpToLine(field);
                return tableField;
            }
        }
        throw new Exception("当前类:"+className+"不存在字段:"+field+"!");
    }

    /**
     * 判断是否存在BuilderField注解
     * @param annotations
     * @return
     */
    public static String hasBuilderField(Annotation[] annotations) {
        if(annotations==null||annotations.length==0)return null;
        for (Annotation annotation : annotations) {
            if(annotation instanceof BuilderField){
                return ((BuilderField) annotation).name();
            }
        }
        return null;
    }


    /**
     * 驼峰转下划线
     * @param str
     * @return
     */
    public static String humpToLine(String str){
        Matcher matcher = humpPattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while(matcher.find()){
            matcher.appendReplacement(sb, "_"+matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 方法名转字段名
     * @param methodName
     * @return
     */
    private String getFieldName(String methodName){
        // 对于非标准变量生成的Get方法这里可以直接抛出异常,或者打印异常日志
        if (GET_PATTERN.matcher(methodName).matches()) {
            methodName = methodName.substring(3);
        } else if (IS_PATTERN.matcher(methodName).matches()) {
            methodName = methodName.substring(2);
        }
        return Introspector.decapitalize(methodName);
    }

    /**
     * 获取query
     * @return
     */
    public Query getQuery() {
        Query query = new Query(criteria);
        return query;
    }

    /***
     * 使用案例
     *
     *         BuilderQuery<OrgV2DO> builderQuery=new BuilderQuery(OrgV2DO.class);
     *         builderQuery.eq(OrgV2DO::getId,"123213");
     *         builderQuery.eq(OrgV2DO::getLastModifiedBy,"123213");
     *         String org = builderQuery.getQuery();
     *         System.out.println(org);
     *
     * ****/
}

 

标签:return,String,val,Mongodb,criteria,boot,field,mongodb,import
From: https://www.cnblogs.com/raorao1994/p/17657094.html

相关文章

  • springboot结合baomidou dynamic-datasource组件实现多数据源
    当系统数据量过大,系统性能问题逐渐浮出水面。使用主从模式,不失是一个较好的选择。即业务在主库执行,不影响业务的查询考虑走从库。这时,程序需要动态多数据源配置。......
  • SpringBoot配置加载方式
    在开发中,我们经常会和配置打交道,SpringBoot为了方便配置的的管理和加载,提供了灵活的配置文件加载机制。它允许从多个来源中加载应用配置信息。如系统默认配置、外部配置文件、环境变量、命令行参数、数据库、配置中心等。下面介绍几种常见的属性来源配置方式。命令行参数Spring......
  • springboot整合redis回滚
    1:添加依赖2:yml中配置连接,如:host,password,port3:@autowired注解注入Redistemplate调用方法生成对象 为了方便公司开发,一般会对数据进行序列化存储,这时需要创建配置类进行全局设置packagecom.example.config;importcom.fasterxml.jackson.annotation.JsonAutoDetect;importco......
  • 基于springboot城镇保障性住房管理系统
    随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了城镇保障性住房管理系统的开发全过程。通过分析城镇保障性住房管理系统管理的不足,创建了一个计算机管理城镇保障性住房管理系统的方案。文章介绍了城镇保障性住房管理系统的系统分析部......
  • 基于SpringBoot的企业资产管理系统
    本企业资产管理系统预期设计的主要功能有用户信息管理、资产分类管理、资产信息管理、资产借出管理、资产归还管理、资产维修管理等模块。通过用户信息管理功能模块,相关使用者可以对用户信息进行管理,比如可以选择修改、删除某位用户,也可以选择增加、查询用户信息。通过资产分类管理......
  • 基于springboot共享汽车管理系统
    随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了共享汽车管理系统的开发全过程。通过分析共享汽车管理系统管理的不足,创建了一个计算机管理共享汽车管理系统的方案。文章介绍了共享汽车管理系统的系统分析部分,包括可行性分析等,系统设......
  • 基于springboot工程教育认证的计算机课程管理平台
    随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了基于工程教育认证的计算机课程管理平台的开发全过程。通过分析基于工程教育认证的计算机课程管理平台管理的不足,创建了一个计算机管理基于工程教育认证的计算机课程管理平台的方案。文......
  • 基于springboot企业级工位管理系统
    随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了企业级工位管理系统的开发全过程。通过分析企业级工位管理系统管理的不足,创建了一个计算机管理企业级工位管理系统的方案。文章介绍了企业级工位管理系统的系统分析部分,包括可行性分析......
  • php mongodb操作类,适合mongodb2.x和mongodb3.x
    在别人基础上修改的mongodb操作类,适合mongodb2.x和mongodb3.x<?php/***Mongodb类**examples:*$mongo=newHMongodb("127.0.0.1:11223");*$mongo->selectDb("test_db");*创建索引*$mongo->ensureIndex("test_table",array(&q......
  • 使用bootstrap总结
    bootstrap是个很不错的前端css框架,把很多按钮、表单、表格、图片css通用样式都写好了,而且浏览器兼容不需我们考虑尤其是它的栅格系统很强大,在做响应式布局时候很有用,但是默认支持12列,一般也足够了,如果要自定义列,就要它的less我没用过,网站性能优化里面有提尽量少用css表达式<!DOC......