# 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中增加一个脚本文件

脚本内容如下(格式必须如此,在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" : "管理员"
}
}'
```

## 数据库存储模式
### 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" : "管理员"
}
}'
```
