# mybatis-plus-jpa-script **Repository Path**: mybatis-plus-jpa/mybatis-plus-jpa-script ## Basic Information - **Project Name**: mybatis-plus-jpa-script - **Description**: 将Java脚本存储到nacos或数据库中,通过Groovy编译能力实现运行时动态编程,具有支持Java原生、亲和Spring框架等优点,同时也解决了频繁发版的问题。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-07-22 - **Last Updated**: 2025-10-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 介绍 将Java脚本存储到nacos或数据库中,通过Groovy编译能力实现运行时动态编程,具有支持Java原生、亲和Spring框架等优点,同时也解决了频繁发版的问题。 # 考虑 场景一:工作中经常会遇到需求变的比女朋友翻脸还快的情况,不断地改代码发版是一件非常痛苦的事情。一直在想有没有这样一个工具,可以在线调试,也可以解决频繁发版的问题。 场景二:有时候,我们需要在测试环境甚至线上环境运行一段代码,用来调试或临时解决问题,用完即删。为了运行这样一段代码进行一次发版或者上线很明显是不太划算的(尤其是有些公司只半夜发版)。 目前主流的解决方案是规则引擎如Drools,这个当然也考虑过([mybatis-plus-jpa-drools](https://gitee.com/mybatis-plus-jpa/mybatis-plus-jpa-drools))。但是规则引擎说实话是不太适合的做这个事情的,一方面规引擎偏脚本化,往往只能固定的做一件事;另一方面与java中主流的框架如spring的结合并没有那么友好。而Groovy天然支持Java原生,不但可以在Groovy脚本中直接编写java代码,甚至可以无缝使用Spring等框架,与直接写Java代码没有差别(完全可以在idea等编程软件中写完代码直接复制过来运行)。 # maven引用 ## 1. 同时使用两种存储模式 ```xml com.xiaoyudeguang mybatis-plus-jpa-boot 1.0.12 com.xiaoyudeguang mybatis-plus-jpa-script com.alibaba.nacos nacos-client 2.4.2 ``` ## 2. 只使用数据库存储模式: ```xml com.xiaoyudeguang mybatis-plus-jpa-boot 1.0.12 com.xiaoyudeguang mybatis-plus-jpa-script com.mysql mysql-connector-j 8.0.33 runtime com.alibaba druid-spring-boot-starter 1.2.16 ``` 或 ```xml org.springframework.boot spring-boot-starter-parent 3.3.3 com.xiaoyudeguang mybatis-plus-jpa-script 1.0.12 com.baomidou mybatis-plus-spring-boot3-starter 3.5.7 com.mysql mysql-connector-j 8.0.33 runtime com.alibaba druid-spring-boot-starter 1.2.16 ``` ## 3. 只使用nacos存储模式: ```xml org.springframework.boot spring-boot-starter-parent 3.3.3 com.xiaoyudeguang mybatis-plus-jpa-script 1.0.12 com.alibaba.nacos nacos-client 2.4.2 ``` # 使用说明 ## nacos存储模式(推荐) ### 1. 在yml中增加nacos配置 ```yml spring: cloud: nacos: discovery: server-addr: ${NACOS_HOST:nacos-server}:${NACOS_PORT:8848} namespace: ${命名空间} metadata: management.context-path: ${management.endpoints.web.base-path:/actuator} health.path: /health config: server-addr: ${spring.cloud.nacos.discovery.server-addr} namespace: ${spring.cloud.nacos.discovery.namespace} file-extension: yml ``` ### 2. 在nacos中增加一个脚本文件 ![输入图片说明](image1.png) 脚本内容如下(格式必须如此,在doService方法中可以编写实现逻辑): ```java package com.xiaoyudeguang.service; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.xiaoyudeguang.service.DynamicService; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; public class DynamicServiceImpl implements DynamicService { private Logger log = LoggerFactory.getLogger(getClass()); @Override public Object doService(HttpServletRequest request, HttpServletResponse response) { return "no-mysql"; } } ``` ### 3. 将下面的curl复制到postman中调用接口 ``` curl --location 'http://127.0.0.1:9999/sysUser/testeee' \ --header 'app_id: 1001' \ --header 'Content-Type: application/json' \ --data '{ "data": { "roleNo": "admin", "roleName" : "管理员" } }' ``` ![输入图片说明](%E8%B0%83%E7%94%A8%E7%A4%BA%E4%BE%8B.png) ## 数据库存储模式 ### 1. 启动类上增加下面的注解: ```yml @EntityScan(basePackages = {"com.**.model"}) @MapperScan(basePackages = {"com.**.mapper"}) ``` ### 2. yml中增加下面的配置 ``` spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource username: root password: 123456 url: jdbc:mysql://mysql-server:3306/demo?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true jpa: hibernate: ddl-auto: update properties: hibernate: enable_lazy_load_no_trans: true schema_update: unique_constraint_strategy: RECREATE_QUIETLY ``` ### 3. 在数据库中执行下面的sql: ``` DROP TABLE IF EXISTS `gv_script`; CREATE TABLE `gv_script` ( `id` bigint NOT NULL COMMENT '主键id', `app_id` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '应用id', `created` datetime DEFAULT NULL COMMENT '创建时间', `creator` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '创建人', `modified` datetime DEFAULT NULL COMMENT '修改时间', `modifier` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '修改人', `sort` int NOT NULL DEFAULT '100000' COMMENT '排序', `status` bigint DEFAULT '0' COMMENT '状态', `tenant_id` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '租户id', `script` text COLLATE utf8mb4_bin COMMENT '脚本内容', `script_key` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '脚本唯一标识', `permission` text COLLATE utf8mb4_bin COMMENT '接口权限', `name` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '脚本名称', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; BEGIN; INSERT INTO `gv_script` (`id`, `app_id`, `created`, `creator`, `modified`, `modifier`, `sort`, `status`, `tenant_id`, `script`, `script_key`, `permission`, `name`) VALUES (1, NULL, NULL, NULL, '2025-08-09 17:41:09', NULL, 100000, 0, NULL, 'package com.xiaoyudeguang.service;\n\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.xiaoyudeguang.service.DynamicService;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.HttpServletResponse;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class DynamicServiceImpl implements DynamicService {\n \n @Override\n public Object doService(HttpServletRequest request, HttpServletResponse response) {\n return \"Groovy动态类12\";\n }\n}', '/sysUser/testeee', NULL, '测试一下4567'); COMMIT; SET FOREIGN_KEY_CHECKS = 1; ``` ### 4. 将下面的curl复制到postman中调用接口 ``` curl --location 'http://127.0.0.1:9999/sysUser/testeee' \ --header 'app_id: 1001' \ --header 'Content-Type: application/json' \ --data '{ "data": { "roleNo": "admin", "roleName" : "管理员" } }' ``` ![输入图片说明](%E5%9B%BE%E7%89%873.png)