初识GroovyShell

文章目录

  • 前言
  • 一、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);
    }

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


在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

谈谈MYSQL主从复制原理

目录 概述 要点binlog日志 主从复制过程 总结 概述 MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。 MySQL 默认采用异步复制方式。从节点不用一直访问主服务器来更新自己的数据&#xff0c;数据的更新可以在远程连接上进行&#xff0…

HTTP 500错误:服务器内部错误,原因及解决方案

大家好&#xff0c;今天我们来聊聊一个常见的问题——HTTP 500错误&#xff0c;也就是服务器内部错误。这个错误就像是一个神秘的魔法&#xff0c;时不时地出现在你的网页上&#xff0c;让你的用户和你在一片懵逼中互相猜疑。 首先&#xff0c;我们来了解一下这个错误。HTTP 5…

LabVIEW在高铁温度与振动监测中的应用

​LabVIEW在高铁温度与振动监测中的应用 高速铁路的可靠性和安全性是现代铁路运输系统设计和运营的重中之重。LabVIEW软件作为一个多功能、可扩展的图形编程环境&#xff0c;提供了一个理想的平台&#xff0c;用于开发高铁监测系统&#xff0c;不仅监测实时数据&#xff0c;也…

数据常见的提取和筛选方法

平时对于一些不标准的数据&#xff0c;需要提取或者筛选其中的部分数据。本文主要分享一些常用的办法&#xff0c;同时也作为一个笔记的备份。 1. 正则表达式 正则表达式比较适合提取有明确类型的数据&#xff0c;比如字母&#xff0c;数字&#xff0c;汉字&#xff0c;日期等…

python自动化测试实战 —— WebDriver API的使用

软件测试专栏 感兴趣可看&#xff1a;软件测试专栏 自动化测试学习部分源码 python自动化测试相关知识&#xff1a; 【如何学习Python自动化测试】—— 自动化测试环境搭建 【如何学习python自动化测试】—— 浏览器驱动的安装 以及 如何更…

Python中的TesserOCR:文字识别的全方位指南

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 文字识别在图像处理领域中起到了至关重要的作用&#xff0c;而TesserOCR&#xff08;Tesseract OCR的Python封装&#xff09;为开发者提供了一个强大的工具&#xff0c;使得文字识别变得更加便捷。本文将通过详细…

MATLAB 最小二乘直线拟合方法二 (36)

MATLAB 最小二乘直线拟合方法二 (36) 一、算法介绍二、算法实现1.代码2.结果一、算法介绍 这里介绍另一种拟合直线点云的方法,更为简单方便,结果与前者一致,主要内容直接复制代码使用即可,原理简单看代码即可,下面是具体的实现和拟合结果展示 二、算法实现 1.代码 代…

死锁的概念

死锁&#xff08;Deadlock&#xff09;、饥饿&#xff08;Starvation&#xff09;和死循环&#xff08;Infinite Loop&#xff09;是计算机科学中与并发和并行处理相关的三个概念&#xff0c;它们描述了不同类型的问题和情况。 死锁&#xff08;Deadlock&#xff09;: 定义: 死…

纯前端使用XLSX导出excel表格

1 单个sheet page.js(页面中的导出方法) import { exportExcel } from ../../../utils/exportExcel.js; leadOut() {const arr [{ id: 1, name: 张三, age: 14, sex: 男 },{ id: 2, name: 李四, age: 15, sex: 女 },{ id: 3, name: 王五, age: 16, sex: 男 },];const allR…

全志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、解…

数据结构从入门到入土——初识泛型

目录 一&#xff0c;包装类 1.基本数据类型和对应的包装类 2.装箱和拆箱 3.自动装箱和自动拆箱 二&#xff0c;什么是泛型&#xff1f; 三&#xff0c;引出泛型 语法 四&#xff0c;泛型类的使用 1.语法 2.类型推导(Type Inference) 五&#xff0c;裸类型(Raw Type) …

Mybatis的foreach标签的使用以及参数的含义

Mybatis的foreach标签的使用以及参数的含义 语法格式&#xff1a; 属性说明&#xff1a; collection属性的注意点&#xff1a;

【UE5.1】套用小白人蓝图,让玩家控制MetaHuman移动

效果 步骤 1. 新建一个工程&#xff0c;创建Basic关卡&#xff0c;添加第三人称游戏资源到内容浏览器 2. 打开Quixel Bridge 选择高质量&#xff0c;然后添加创建好的MetaHuman到内容浏览器 启用所有缺失 立即重启 添加完毕后内容浏览器会多出“MetaGumans”文件夹&#xff0…

字符处理 C语言xdoj52

问题描述 从键盘输入一个字符&#xff0c;若为小写字母&#xff0c;则输出其对应的大写字母&#xff1b;若为大写字母&#xff0c;则输出对应的小写字母&#xff1b;其他字符原样输出。 输入说明 输入一个字符 输出说明 输出一个字符 输入样例 样例1输入 a 样例…

再回首感知损失在low-level上的应用

《Perceptual Losses for Real-Time Style Transfer and Super-Resolution》是李飞飞团队在2016年发表于ECCV的文章。我近几年的工作中&#xff0c;所训练的模型都离不开感知损失。不得不感慨&#xff0c;大佬之所以是大佬&#xff0c;就是因为他们开创性的工作很多年后依然为人…

生成树基本实验

背景 某公司的二层交换网络中&#xff0c;为了提高网络可靠性&#xff0c;故在二层交换网络中增加冗余链路。为了阻 止冗余链路可能带来的广播风暴&#xff0c;MAC地址漂移等负面影响&#xff0c;需要在交换机之间部署生成树 协议。 实验 一.配置stp en 开启 stp en stp …

2021实战面试

1、Rem , em , px , % , vw 之间的区别 PX: px像素&#xff08;Pixel&#xff09;。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。 em: 1,子元素字体大小的em是相对于父元素字体大小 2,元素的width/height/padding/margin用em的话是相对于该元素的font-size rem:1rem是…

计算机毕业设计 SpringBoot的供应商管理系统 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

Kafka-集群架构设计

Kafka的Zookeeper元数据梳理 zookeeper整体数据 Kafka将状态信息保存在Zookeeper中&#xff0c;这些状态信息记录了每个Kafka的Broker服务与另外的Broker服务 有什么不同。通过这些差异化的功能&#xff0c;共同体现出集群化的业务能力。这些数据&#xff0c;需要在集群中各个…

道路清障车行业分析:中国市场发展趋势研究

清障车全名为道路清障车&#xff0c;又称拖车、道路救援车、拖拽车&#xff0c;具有起吊、拽拉和托举牵引等多项功能&#xff0c;清障车主要用于道路故障车辆&#xff0c;城市违章车辆及抢险救援等。清障车按类别主要分为&#xff1a;拖吊连体型、拖吊分离型&#xff0c;一拖一…