初识GroovyShell

news2024/11/15 11:03:55

文章目录

  • 前言
  • 一、GroovyShell
  • 二、maven
  • 三、解决方案
  • 四、关键代码
    • 4.1 数据库配置表(pg)
    • 4.2 入参
    • 4.3 分页查询
  • 总结


前言

项目背景:查询多个表的数据列表和详情,但不想创建过多的po、dao、resp等项目文件。

一、GroovyShell

Apache Groovy是一种强大的、可选的类型和动态语言,具有静态类型和静态编译功能,用于Java平台,旨在通过简洁、熟悉和易于学习的语法提高开发人员的生产力。它可以与任何Java程序顺利集成,并立即为您的应用程序提供强大的功能,包括脚本功能、领域特定语言创作、运行时和编译时元编程以及函数式编程。

二、maven

      <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.4.7</version>
        </dependency>

三、解决方案

  1. 数据存储sql(条件查询)
  2. 根据资源名称和条件入参查询sql
  3. GroovyShell获取sql
  4. 查询数据

四、关键代码

4.1 数据库配置表(pg)

INSERT INTO "data_resource"."resource_query_config" ("id", "resource_code", "resource_desc", "resource_sql") VALUES ('8a8ae4db8a1bf1cf018a1c1c0656004e', 'hospital_info', '医院-详情查询', 'def infoSql(String id) {
    StringBuilder sb = new StringBuilder();
    sb.append(" SELECT A.id,A.pac,A.name,A.address,A.levelcode,A.ownshipcode,A.area,A.buildingarea,B.respoperson,B.fillinpersontel,B.powersupplycode,B.watersupplycode,B.heatsupplycode,B.commsupportcode,B.plantypecode  FROM hel_helthorg_p A  ")
sb.append("LEFT JOIN helthorg_p_bu B ON A.id = B.gid ")
            .append(" WHERE A.ID = ''").append(id).append("''");
    return sb.toString();
}');
INSERT INTO "data_resource"."resource_query_config" ("id", "resource_code", "resource_desc", "resource_sql") VALUES ('ff80808189914fbe018996854a420001', 'hospital_page', '医院-分页查询', 'import org.apache.commons.lang3.StringUtils

def pageListSql(Map<String, Object> map) {
    StringBuilder sb = new StringBuilder();
    sb.append(" SELECT A.id, A.name,d.featurename,A.address,A.pac,B.respoperson,B.fillinpersontel,A.longitude,A.latitude ")
            .append(" FROM helthorg_p A LEFT JOIN helthorg_p_bu B ON A.id = B.gid ")
            .append(" LEFT JOIN code_feature d ON A.featurecode = d.featurecode WHERE a.isdeleted = ''0'' ");
    if (StringUtils.isNotBlank(map.get("distCode"))) {
        sb.append(" AND A.pac like :distCode ")
    }
    if (StringUtils.isNotBlank(map.get("resName"))) {
        sb.append(" AND A.NAME like :resName ")
    }
    return sb.toString();
}');
INSERT INTO "data_resource"."resource_query_config" ("id", "resource_code", "resource_desc", "resource_sql") VALUES ('ff80808189914fbe018996854a420013', 'hotel_info', '宾馆饭店-详情查询', 'def infoSql(String id) {
    StringBuilder sb = new StringBuilder();
    sb.append(" SELECT A.id, A.name,A.address,A.pac,A.ownshipcode as GAT_OWNSHIPCODE,A.starcode as HOTL_STARCODE,")
            .append(" A.area,A.buildingarea,B.roomnum,B.bednum,B.meetmaxhold,B.respoperson,B.fillinpersontel,B.powersupplycode,B.watersupplycode,B.heatsupplycode,B.commsupportcode,B.plantypecode,A.longitude,A.latitude ")
            .append(" FROM hotel_p A LEFT JOIN hotel_p_bu B ON A.id = B.gid ")
            .append(" WHERE A.ID = ''").append(id).append("''");
    return sb.toString();
}');
INSERT INTO "data_resource"."resource_query_config" ("id", "resource_code", "resource_desc", "resource_sql") VALUES ('ff80808189914fbe018996854a420012', 'hotel_page', '宾馆饭店-分页查询', 'import org.apache.commons.lang3.StringUtils

def pageListSql(Map<String, Object> map) {
    StringBuilder sb = new StringBuilder();
    sb.append(" SELECT A.id, A.name,A.address,A.pac,B.respoperson,B.fillinpersontel,A.longitude,A.latitude ")
            .append(" FROM hotel_p A LEFT JOIN hotel_p_bu B ON A.id = B.gid ")
            .append(" WHERE a.isdeleted = ''0'' ");
    if (StringUtils.isNotBlank(map.get("distCode"))) {
        sb.append(" AND A.pac like :distCode ")
    }
    if (StringUtils.isNotBlank(map.get("resName"))) {
        sb.append(" AND A.NAME like :resName ")
    }
    return sb.toString();
}');

4.2 入参

@QueryField 为封装jpa查询注解

/**
 * 资源查询类
 */
@Data
public class ResourceQO extends PageQO {
    /**
     * 资源标识
     */
    private String resCode;
    /**
     * 数据主键
     */
    private List<String> id;
    /**
     * 行政区划编码
     */
    @QueryField(type = QueryType.RIGHT_LIKE)
    private String distCode;
    /**
     * 资源名称
     */
    @QueryField(type = QueryType.FULL_LIKE)
    private String resName;

}

4.3 分页查询

    public PageResult<Map<String, Object>> pageList(ResourceQO qo){
    	//根据条件查询并拼接配置表数据
        Optional<ResourceQueryConfigPO> rqc =  dao.findByResourceCode(qo.getResCode());
        BizPreconditions.checkArgumentNoStack(rqc.isPresent(), "资源标识不存在");
        // 处理区划编码;查询当前区划下的所有数据,截取,右 like
        qo.setDistCode(processDistCode(qo.getDistCode()));
        // 动态获取SQL
        GroovyShell groovyShell = new GroovyShell();
        //装载解析脚本代码
        Script script = groovyShell.parse(rqc.get().getResourceSql());
        //执行
        String json = JsonUtil.of(qo);
        Map<String, Object> map = JsonUtil.ofMap(json, String.class, Object.class);
        String pageSql = (String) script.invokeMethod("pageListSql", map);
        String countSql = " select count(*) from ( " + pageSql +") as pc ";
        //jpa执行分页查询sql,并封装map返回
        Page<Map<String, Object>> pageList = dao.executeNativePageQuery(pageSql, countSql, qo);
        return PageAdapter.adapter(pageList, p -> p.getContent());
    }

总结

案例中有很多自定义封装的类,下面给出GroovyShell简单示例
SpringContextUtilneTypeToHdTypeServiceImpl都是spring注入的bean

  1. SpringContextUtil是获取bean的通用工具,可参考 SpringBoot 获取bean
  2. NeTypeToHdTypeServiceImpl是具体业务服务
    @GetMapping("/v1/test/{neId}")
    public Result<List<HdTypeResp>> test(@PathVariable Integer neId){
        //创建GroovyShell
        GroovyShell groovyShell = new GroovyShell();
        //装载解析脚本代码
        Script script = groovyShell.parse("package groovy\n" +
                "\n" +
                "import com.gsafety.bg.si.manage.service.NeTypeToHdTypeService\n" +
                "import com.gsafety.bg.si.manage.service.util.SpringContextUtil\n" +
                "\n" +
                "void HelloWorld(){\n" +
                "    println \"\\033[33mhello world\\033[0m\"\n" +
                "}\n" +
                "\n" +
                "def findHdIdsByNeId(Integer neId) {\n" +
                "    NeTypeToHdTypeService service = SpringContextUtil.getBean(\"neTypeToHdTypeServiceImpl\")\n" +
                "    return service.findHdIdsByNeId(neId);\n" +
                "}\n");
        //执行HelloWorld
        script.invokeMethod("HelloWorld", null);
        //执行findHdIdsByNeId
        List<HdTypeResp> resps =  (List<HdTypeResp>)script.invokeMethod("findHdIdsByNeId", neId);
        resps.forEach(r->{
            System.out.println("\033[32m"+r+"\033[0m");
        });
        return Result.success(resps);
    }

输出结果:
在这里插入图片描述


在这里插入图片描述

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

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

相关文章

关于ctf反序列化题的一些见解([MRCTF2020]Ezpop以及[NISACTF 2022]babyserialize)

这里对php反序列化做简单了解 在PHP中&#xff0c;序列化用于存储或传递 PHP 的值的过程中&#xff0c;同时不丢失其类型和结构。 serialize&#xff08;&#xff09; 函数序列化对象后&#xff0c;可以很方便的将它传递给其他需要它的地方&#xff0c;且其类型和结构不会改变…

Python FuckIt模块:代码的“不死鸟”

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 在编程世界中&#xff0c;每个开发者都曾遇到过代码中的错误&#xff0c;有时这些错误可能让人崩溃。但是&#xff0c;有一天&#xff0c;听说了一个叫做"FuckIt"的模块&#xff0c;它声称可以帮助摆脱…

ASP.NET Core 8 在 Windows 上各种部署模型的性能测试

ASP.NET Core 8 在 Windows 上各种部署模型的性能测试 我们知道 Asp.net Core 在 windows 服务器上部署的方案有 4 种之多。这些部署方案对性能的影响一直以来都是靠经验。比如如果是部署在 IIS 下&#xff0c;那么 In Process 会比 Out Process 快&#xff1b;如果是 Self Hos…

计算机操作系统-第十六天

目录 线程的实现方式 用户级线程 内核级线程 多线程模型 一对一模型 多对多模型 多对多模型 本节思维导图 线程的实现方式 用户级线程 历史背景&#xff1a;早期操作系统只支持进程&#xff0c;不支持线程&#xff0c;当时的线程是由线程库实现的 本质&#xff1a;从…

zabbix简单介绍2

学习目标: 能够实现一个web页面的监测能够实现自动发现远程linux主机能够通过动作在发现主机后自动添加主机并链接模板能够创建一个模版并添加相应的元素(监控项,图形,触发器等)能够将主机或模板的配置实现导出和导入能够实现至少一种报警方式(邮件,微信等)能够通过zabbix_pro…

中兴 H108NS 路由器 tools_admin.asp权限绕过漏洞复现

0x01 产品简介 中兴H108NS路由器是一款集WiFi管理、路由分配、动态获取上网连接等功能于一体的路由器产品。 0x02 漏洞概述 中兴H108NS路由器tools_admin.asp接口处存在身份认证绕过漏洞,攻击者可利用该漏洞绕过身份认证允许访问路由器的管理面板修改管理员密码,获取用户的…

全志V3s之U-Boot

1、安装交叉编译器&#xff1a; ARM交叉编译器的官网&#xff1a;交叉编译器 a、使用wget下载&#xff1a; wget https://releases.linaro.org/components/toolchain/binaries/latest/arm-linux-gnueabihf/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf.tar.xzb、解…

关于“Python”的核心知识点整理大全12

目录 6.3.3 按顺序遍历字典中的所有键 6.3.4 遍历字典中的所有值 6.4 嵌套 6.4.1 字典列表 aliens.py 6.4.2 在字典中存储列表 pizza.py favorite_languages.py 注意 往期快速传送门&#x1f446;&#xff08;在文章最后&#xff09;&#xff1a; 6.3.3 按顺序遍历字…

a16z:加密行业2024趋势“无缝用户体验”

近日&#xff0c;知名加密投资机构a16z发布了“Big ideas 2024”&#xff0c;列出了加密行业在 2024 年几个具备趋势的“大想法”&#xff0c;其中 Seamless UX&#xff08;无缝用户体验&#xff09;赫然在列。 从最为直观的理解上&#xff0c;Seamless UX 是在强调用户在使用产…

物联网时代的访问控制研究综述

A survey on Access Control in the Age of Internet of Things 文章目录 A B S T R A C T引言A. Comparison Between This Paper and Existing SurveysB. Contributions II.ACCESS CONTROL BACKGROUNDIII. ACCESS CONTROL CHALLENGES IN IOT SEARCHA. Characteristics of IoT …

一个简单得爬虫小案例:获取西瓜网视频数据【python】

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 第三方模块: requests >>> pip install requests 环境介绍: python 3.8 解释器 pycharm 编辑器 思路分析 找到数据来源 你要爬取的视频 筛选 找不…

EasyX图形化学习(二)

1.消息处理---鼠标消息&#xff1a; 1.ExMessage结构体&#xff1a; ExMessage---这个结构体用于保存鼠标消息。 //定义消息结构体变量 ExMessage msg { 0 }; 2.获取消息&#xff1a; &#xff08;1&#xff09;peekmessage函数&#xff1a;用于获取一个消息&#xff0c;…

leetcode面试经典150题——36 旋转图像

题目&#xff1a; 旋转图像 描述&#xff1a; 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#x…

【论文阅读】LoRA: Low-Rank Adaptation of Large Language Models

code&#xff1a;GitHub - microsoft/LoRA: Code for loralib, an implementation of "LoRA: Low-Rank Adaptation of Large Language Models" 做法&#xff1a; 把预训练LLMs里面的参数权重给冻结&#xff1b;向transformer架构中的每一层&#xff0c;注入可训练的…

MYSQL练题笔记-子查询-换座位

一、题目相关内容 1&#xff09;相关的表和题目 2&#xff09;帮助理解题目的示例&#xff0c;提供返回结果的格式 二、自己初步的理解 没啥思路&#xff0c;我还没做过交换的这种题&#xff0c;所以我觉得这类交换的题以后值得做一个合集&#xff0c;是有点灵活度在里面的&a…

智能优化算法应用:基于黄金正弦算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于黄金正弦算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于黄金正弦算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.黄金正弦算法4.实验参数设定5.算法结果6.…

【Proteus仿真】【51单片机】视力保护仪

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使LCD1602液晶&#xff0c;按键、HC-SR04超声波、PCF8591 ADC、光敏传感器、蜂鸣器、LED等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示…

云计算:Vmware 安装 FusionCompute

目录 一、理论 1.FusionCompute 二、实验 1.Vmware 安装 FusionCompute&#xff08;CNA&#xff09; 2.Vmware 安装 FusionCompute&#xff08;VRM&#xff09; 三、问题 1. VRM-WEB登录失败 2.Windows cmd中无法ping通虚拟机 一、理论 1.FusionCompute &#xff08;…

【C语言】操作符详解(四):结构成员访问操作符

结构成员访问操作符 结构体 ⭐C语言已经提供了内置类型&#xff0c;如: char、short、int、long、float、double等&#xff0c;但是只有这些内置类型还是不够的&#xff0c;假设我想描述学生&#xff0c;描述一本书&#xff0c;这时单一的内置类型是不行的。描述一个学生需要名…

Android VpnService 使用(一)

Android VpnService 使用(一) 本篇算是VpnService 使用的第一篇文章,主要讲述service创建,intent调用. 1: 申请权限 <service android:name".MyVpnService" android:permission"android.permission.BIND_VPN_SERVICE"><intent-filter><ac…