我做了一个JPA Specification的优化

news2024/12/28 19:58:36

目录

  • 一、参考
  • 二、概述
    • 流程
    • 效果感受
  • 三、实现原理
    • AST树结构
      • AstNode主要结构
    • 把表达式解析成Ast
    • Ast 解析成 JPA Specification
  • 三、项目地址
  • 四、目前阶段的总结

一、参考

如何搞一个支持自定义函数和变量的四则运算的抽象语法树出来

二、概述

这是一个可以优化生成Specification对象的轮子,目前处于一个不太靠近中间的产品。

流程

在这里插入图片描述

效果感受

这是随便测试的一个例子,与下面讲解的例子不一样。
在这里插入图片描述

Specification正常的写法:

public Page<Image> pagingImage(String title, Integer start, Integer size) {
    Pageable pageable = PageRequest.of(start, size, Sort.by(Sort.Direction.DESC , "id"));
    Specification<Image> specification = (root, query, criteriaBuilder) -> {
        List<Predicate> and = new ArrayList<>();
        and.add(criteriaBuilder.like(root.get("title").as(String.class), String.format("%%%s%%", title)));
        and.add(criteriaBuilder.notLike(root.get("file").as(String.class), "%http://%"));
        and.add(criteriaBuilder.notLike(root.get("file").as(String.class), "%https://%"));
        List<Predicate> and$2 = new ArrayList<>();
        and$2.add(criteriaBuilder.equal(root.get("status").as(Integer.class), 3));
        and$2.and(criteriaBuilder.equal(root.get("deleted").as(Boolean.class), false));
        return criteriaBuilder.or(and.toArray(new Predicate[and.size()]), and$2.toArray(new Predicate[and$2.size()]));
    };
    Page<Image> page = imageRepository.findAll(specification, pageable);
    return page;
}

目前的写法:

private final SpecificationApplication<GroundEntity> specificationApplication = new SpecificationApplication<>(Image.class);

public Page<Image> pagingImage(String title, Integer start, Integer size) {
    Pageable pageable = PageRequest.of(start, size, Sort.by(Sort.Direction.DESC , "id"));
    String sql$1 = "file not like %http://% and file not like %https://%";
    String sql = String.format("(title like %%%s%% and %s) or (status=3 and deleted=false)", title, sql$1);
    Specification<Image> specification = specificationApplication.specification(sql);
    Page<Image> page = imageRepository.findAll(specification, pageable);
    return page;
}

上面的代码相对来说确实少了一些,但是字段在IDEA中没有提示、关键字没有提示,所以这是后面的改进方向,后面会用链式调用去改进,还有sql字段也没有相对应的验证,根据验证来决定拼接sql。

未来的写法可能是这样:

public Page<Image> pagingImage(String title, Integer start, Integer size) {
    Pageable pageable = PageRequest.of(start, size, Sort.by(Sort.Direction.DESC , "id"));
    Image image = new Image();
    Specification<Image> specification = image.openBracket()
        .title().notLike("%http://%")
        .and()
        .file().notLike("%https://%")
        .closeBracket()
        .openBracket()
        .or()
        .status().eq(3)
        .deleted().eq(false)
        .build();
    Page<Image> page = imageRepository.findAll(specification, pageable);
    return page;
}

因为在IDEA这样的编辑器中,方法都是有提示的,所有写上面的代码会显得非常轻松。但还是不够的,因为SQL要动态拼接,如何更加方便的进行拼接还是需要思考的问题。

三、实现原理

AST树结构

在这里插入图片描述

AstNode主要结构

  • AstDichotomyOperation

表达式由左右两边构成,左右两边都可以解析。
如:expression and expression

  • AstNoDichotomyOperation

表达式只有变量和关键字构成,不能继续解析。
如:xxx IS NULL | xxx IS NOT NULL | xxx ISNULL…

  • AstSymmetryOperation

单边的表达式,该表达式的右边还会继续解析。
如:!(expression) / not(expression)

  • AstStatic

最终的节点,无法被继续分析。

在这里插入图片描述

把表达式解析成Ast

  • AbstractOperationHandle:解决字符串的解析。
  • NoDichotomyHandle:解析 xxx IS NULL | xxx IS NOT NULL | xxx ISNULL …
  • DichotomyHandle:解析expression and expression。
  • SymmetryHandle:解析!(expression) / not(expression)
  • BracktHandle:解析(expression)

在这里插入图片描述

Ast 解析成 JPA Specification

感觉过程有点复杂,简单点描述来说,就是深度搜索AST树,在先序、中序、后序中分别让表达式入栈出栈的过程,最后predicate栈剩下的一个元素就是我们需要的Predicate。类协同比较核心的图我给出来,但是过程太过麻烦,就不给图了。

  • AstRecursion 深度搜索
  • OperationOrStaticHandle 协同各种逻辑、变量、值入栈出栈、创建Predicate并入栈出栈
  • StackParse 四个栈,存储值、变量、Predicate
  • PredicateGenerate 一个抽象的接口,用于创建对于类型的Predicate

在这里插入图片描述

三、项目地址

https://gitee.com/jiangjinghong520/jpa-specification.git

四、目前阶段的总结

目前是不能支持链式调用的中间产品,先一步一步做中间产品,做链式挺简单,但是要做好还是挺难,得研究一下SpringSecurity中build/config和Java Stream的设计,模仿它们。要更加方便的编程,还要借鉴lombok,掌握JSR 256技术。一下子是完全做不出来的,对于我来说一下子要学的东西还挺多,我觉得也挺难。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/835208.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android SystemServer中Service的创建和启动方式(基于Android13)

Android SystemServer创建和启动方式(基于Android13) SystemServer 简介 Android System Server是Android框架的核心组件&#xff0c;运行在system_server进程中&#xff0c;拥有system权限。它在Android系统中扮演重要角色&#xff0c;提供服务管理和通信。 system …

Pycharm中修改注释文本的颜色(详细设置步骤)

下面是在Pycharm中设置注释文本颜色的详细步骤&#xff1a; 下面是修改前后对比&#xff1a; 修改前注释行的颜色&#xff1a; 修改后注释行的颜色&#xff1a; 以上就是Pycharm中修改注释文本颜色的详细步骤&#xff0c;希望能帮到你&#xff01;

pve安装dsm7.2,并启用照片同步

目录 1.文件准备 2. 创建虚拟机 3. 编译引导文件 4. 群晖安装 5. 安装Photos和mmfpeg 6. 安装手机APP 之前安装了pve版本的dsm6.2了&#xff0c;近期换硬盘&#xff0c;加上对dsm6.2的moments性能实在不满意&#xff0c;就产生尝鲜的想法&#xff0c;因为dsm7.0发布很久了…

2024年浙财MBA项目招生信息全面了解

2024年全国管理类硕士联考备考已经到了最火热的阶段&#xff0c;不少考生开始持续将注意力集中在备考的规划中&#xff01;杭州达立易考教育整合浙江省内的MBA项目信息&#xff0c;为大家详细梳理了相关报考参考内容&#xff0c;方便大家更好完成择校以及针对性的备考工作。本期…

Day12-作业(SpringBootWeb登录认证)

作业1&#xff1a;完成课上所讲解的 登录 及 登录校验 的所有功能。[ 必须 &#xff0c;至少敲两遍 - Filter] 作业2&#xff1a;调研第三方加密技术和落地方案&#xff0c;优化登录业务流程。 提示&#xff1a;推荐使用加盐加密的方式&#xff0c;对密码进行加密并校验 作业3…

【快应用】adbutton如何直接下载广告而不跳落地页再下载

【关键词】 原生广告、adbutton、下载 【问题背景】 快应用中的原生广告推出了adbutton组件来直接下载广告app&#xff0c;在使用的时候&#xff0c;点击adbutton按钮的安装文案&#xff0c;不是直接下载广告app&#xff0c;而是跳转到落地页后直接下载&#xff0c;这种情形该…

企业工程项目管理系统源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理) em

​ 工程项目管理软件&#xff08;工程项目管理系统&#xff09;对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营&#xff0c;全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…

cad中的曲线区域是如何绘制的

cad中的曲线区域是如何绘制的 最近需要把cad中的设备锁在区域绘画出来&#xff0c;不同设备放在不同区域 组合工具命令PLPE 步骤&#xff1a; 1.先用pl绘制&#xff0c;把设备都是绘制在pl的曲线范围内 2.用pe命令&#xff0c;选择pl的区域进行曲线&#xff08;s&#xff…

基于SpringBoot+Vue的MOBA类游戏攻略分享平台设计与实现(源码+LW+部署文档等)

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

软考A计划-系统集成项目管理工程师-信息文档和配置管理-下

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

华为杯竞赛、高教社杯和数学建模国赛实现逆袭;评奖评优加分冲冲冲!

目录 ⭐ 赛事介绍 ⭐ 参赛好处 ⭐ 辅导比赛 ⭐ 赛事介绍 华为杯全国研究生数学建模竞赛是由华为公司主办的一项面向全国研究生的数学建模竞赛。该竞赛旨在通过实际问题的建模和解决&#xff0c;培养研究生的创新能力和团队合作精神&#xff0c;推动科技创新和应用。华为杯竞…

【超细节】Vue3的属性传递——Props

目录 前言 一、定义 二、使用 1. 在 setup 中&#xff08;推荐&#xff09; 2. 非 setup 中 3. 对象写法的校验类型 4. 使用ts进行类型约束 5. 使用ts时props的默认值 三、注意事项 1. Prop 名字格式 2. 对象或数组类型的默认值 3. Boolean 类型转换 前言 Vue3相较…

代码签名证书是什么?

代码签名证书是什么&#xff1f;有什么作用&#xff1f;代码签名证书是提供软件开发者可以进行代码软件数字签名的认证服务。通过对代码的数字签名可以消除软件在Windows系统被下载安装时弹出的“不明开发商”安全警告&#xff0c;保证代码完整性和不被恶意篡改&#xff0c;使软…

【严重】泛微 e-cology <10.58.3 任意文件上传漏洞

漏洞描述 泛微协同管理应用平台(e-cology)是一套企业大型协同管理平台。 泛微 e-cology 10.58.3之前版本存在任意文件上传漏洞&#xff0c;由于上传接口身份认证缺失&#xff0c;未经过身份验证的攻击者可以构造恶意请求将文件上传至服务器&#xff0c;攻击者可能通过上传jsp…

Python web实战之 Django 的模板语言详解

关键词&#xff1a; Python、web开发、Django、模板语言 概要 作为 Python Web 开发的框架之一&#xff0c;Django 提供了一套完整的 MVC 模式&#xff0c;其中的模板语言为开发者提供了强大的渲染和控制前端的能力。本文介绍 Django 的模板语言。 1. Django 模板语言入门 Dj…

神策新一代分析引擎架构演进

近日&#xff0c;神策数据已经推出全新的神策分析 2.5 版本&#xff0c;该版本支持分析模型与外部数据的融合性接入&#xff0c;构建全域数据融合模型&#xff0c;实现从用户到经营的全链路、全场景分析。新版本的神策分析能够为企业提供更全面、更有效的市场信息和经营策略&am…

《向量数据库指南》——腾讯云向量数据库Tencent Cloud VectorDB产品规格

目录 节点类型 节点数量 节点规格 腾讯云向量数据库(Tencent Cloud VectorDB)采用分布式部署架构,每个节点相互通信和协调,实现数据存储与检索。客户端请求通过 Load balance 分发到各节点上。具体信息,请参见 产品架构。 节点类型 腾讯云向量数据库依据存储节点 CPU …

A02_启动测速和切换站点

一 业务功能 二 问题 三 业务流程 1 初始化网络 2 测速选站点 3 拉取站点 4 手动切换站点 四 重点代码 public class StationMeasure {private static final String TEST_STATION_URL "/test/ips";private static final String STATION_URL "/product/ips&…

鸟哥马哥共叙Linux发展

导读北京时间3月28日&#xff0c;由51CTO学院和人民邮电出版社信息技术分社联合举办的[开放见远]“鸟哥”大陆行Linux技术沙龙在位于北京市西三环久凌大厦的51CTO学院举行。 台湾著名Linux网站——“鸟哥的Linux私房菜”站长蔡德明&#xff0c;51CTO学院讲师马哥教育创始人马永…

EasyRecovery15简体中文个人版专业手机数据恢复软件

EasyRecovery15数据恢复软件是一款文件恢复软件&#xff0c;能够恢复内容类型非常多&#xff0c;包括办公文档、文件夹、电子邮件、照片、音频等一些常用文件类型都是可以进行恢复&#xff0c;操作非常简单&#xff0c;只需要将存储设备连接到电脑上&#xff0c;运行EasyRecove…