添加 Magic-API 接口快速开发框架的脚本编写助手
This commit is contained in:
parent
b2d286035b
commit
8c6bec031b
18
magic-script-skill/.gitignore
vendored
Normal file
18
magic-script-skill/.gitignore
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Build and Release Folders
|
||||||
|
bin-debug/
|
||||||
|
bin-release/
|
||||||
|
[Oo]bj/
|
||||||
|
[Bb]in/
|
||||||
|
|
||||||
|
# Other files and folders
|
||||||
|
.settings/
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.swf
|
||||||
|
*.air
|
||||||
|
*.ipa
|
||||||
|
*.apk
|
||||||
|
|
||||||
|
# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
|
||||||
|
# should NOT be excluded as they contain compiler settings and other important
|
||||||
|
# information for Eclipse / Flash Builder.
|
||||||
21
magic-script-skill/LICENSE
Normal file
21
magic-script-skill/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 Assassin-Q
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
154
magic-script-skill/SKILL.md
Normal file
154
magic-script-skill/SKILL.md
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
---
|
||||||
|
name: magic-script
|
||||||
|
description: magic-api 框架接口开发助手,提供 magic-script 脚本编写指导、DB/HTTP 模块使用及语法纠错;当用户需要在 magic-api 中编写接口脚本、调试脚本或排查脚本错误时使用
|
||||||
|
---
|
||||||
|
|
||||||
|
# Magic-Script 脚本开发助手
|
||||||
|
|
||||||
|
Magic-API 是一个基于 Java 的接口快速开发框架,支持通过 magic-script 脚本语言编写接口。magic-script 是一种基于 Mozilla Rhino 的脚本语言,语法类似 JavaScript,专为接口开发优化。
|
||||||
|
|
||||||
|
> **说明**:本 Skill 同时兼容以下称呼方式:
|
||||||
|
> - magic-api / magicapi(框架名称)
|
||||||
|
> - magic-script / MagicScript / magicscript(脚本语言名称)
|
||||||
|
> 无论用户使用哪种称呼,都指代同一套技术栈。
|
||||||
|
|
||||||
|
## 任务目标
|
||||||
|
- 本 Skill 用于:为 magic-api/magicapi 框架提供 magic-script/MagicScript 脚本编写的完整指导
|
||||||
|
- 能力包含:magic-script 语法参考、内置模块(db、http 等)使用方法、接口开发示例和脚本故障排查
|
||||||
|
- 触发条件:用户需要在 magic-api/magicapi 中编写接口脚本、调试 magic-script/MagicScript 代码或解决脚本执行错误时使用
|
||||||
|
|
||||||
|
## 操作步骤
|
||||||
|
- 标准流程:确认场景 → 阅读 SKILL.md → 查阅 references/ 文档 → 编写脚本
|
||||||
|
- 可选分支:遇到脚本错误 → 查阅 faq 相关文档
|
||||||
|
|
||||||
|
## 使用示例
|
||||||
|
|
||||||
|
**示例1:快速查询接口**
|
||||||
|
```javascript
|
||||||
|
// GET /api/user/list 分页查询
|
||||||
|
return db.table('sys_user')
|
||||||
|
.column('id', 'userId')
|
||||||
|
.column('name', 'userName')
|
||||||
|
.where()
|
||||||
|
.eq('status', 1)
|
||||||
|
.page(page, size);
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例2:带参数的增删改查**
|
||||||
|
```javascript
|
||||||
|
// POST /api/user/save 新增用户
|
||||||
|
assert not_blank(body.name) : 400, '用户名不能为空';
|
||||||
|
var userId = db.table('sys_user')
|
||||||
|
.column('name', body.name)
|
||||||
|
.column('create_time', now())
|
||||||
|
.insert();
|
||||||
|
return {code: 200, data: {id: userId}};
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例3:调用外部接口**
|
||||||
|
```javascript
|
||||||
|
import http;
|
||||||
|
var result = http.connect('https://api.example.com/data')
|
||||||
|
.param({key: 'value'})
|
||||||
|
.header('Authorization', 'Bearer xxx')
|
||||||
|
.post()
|
||||||
|
.getBody();
|
||||||
|
return result;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 资源索引
|
||||||
|
|
||||||
|
### 语法类
|
||||||
|
| 文件 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `references/keywords.md` | 关键字、运算符、数据类型 |
|
||||||
|
| `references/script-syntax.md` | 脚本语法详解 |
|
||||||
|
| `references/lambda-async.md` | Lambda表达式与异步调用 |
|
||||||
|
|
||||||
|
### 函数扩展
|
||||||
|
| 文件 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `references/aggregation.md` | 聚合函数(count/sum/max/min/avg/group_concat) |
|
||||||
|
| `references/string-functions.md` | 字符串函数(uuid/is_blank/not_blank) |
|
||||||
|
| `references/date-functions.md` | 日期函数(date_format/now/current_timestamp_millis/current_timestamp) |
|
||||||
|
| `references/number-extensions.md` | Number扩展与数学函数 |
|
||||||
|
| `references/collection-extensions.md` | 列表与Map扩展 |
|
||||||
|
| `references/date-extensions.md` | 日期扩展 |
|
||||||
|
| `references/array-functions.md` | 数组创建函数 |
|
||||||
|
| `references/math-functions.md` | 数学函数(round/floor/ceil/percent) |
|
||||||
|
| `references/other-functions.md` | 其它函数(print/println/ifnull/is_null/not_null) |
|
||||||
|
| `references/object-extensions.md` | Object扩展方法 |
|
||||||
|
| `references/class-extensions.md` | Class扩展方法 |
|
||||||
|
| `references/pattern-extensions.md` | Pattern扩展方法 |
|
||||||
|
|
||||||
|
### 数据库
|
||||||
|
| 文件 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `references/db-query.md` | 数据库查询(select/selectOne/selectInt/selectValue) |
|
||||||
|
| `references/db-update.md` | 数据库增删改(insert/update/batchUpdate/call) |
|
||||||
|
| `references/db-transaction.md` | 事务操作 |
|
||||||
|
| `references/db-cache.md` | 缓存操作(cache/deleteCache) |
|
||||||
|
| `references/single-table.md` | 单表操作(db.table链式API) |
|
||||||
|
| `references/sql-param.md` | SQL参数(#{}、${}、动态SQL、Mybatis语法) |
|
||||||
|
| `references/page.md` | 分页查询 |
|
||||||
|
|
||||||
|
### 模块
|
||||||
|
| 文件 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `references/http-module.md` | HTTP模块调用外部接口 |
|
||||||
|
| `references/request-module.md` | Request模块获取请求信息 |
|
||||||
|
| `references/response-module.md` | Response模块设置响应 |
|
||||||
|
| `references/log-module.md` | 日志模块 |
|
||||||
|
| `references/env-module.md` | 环境配置模块 |
|
||||||
|
| `references/magic-module.md` | Magic模块(调用其他接口) |
|
||||||
|
|
||||||
|
### 集成
|
||||||
|
| 文件 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `references/java-integration.md` | 脚本调用Java |
|
||||||
|
| `references/api-integration.md` | Java调用接口 |
|
||||||
|
|
||||||
|
### 示例
|
||||||
|
| 文件 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `references/quick-start.md` | 快速入门(工程创建、三分钟写接口) |
|
||||||
|
| `references/quick-param.md` | 请求参数获取 |
|
||||||
|
| `references/quick-crud.md` | CRUD操作示例 |
|
||||||
|
| `references/linq.md` | Lambda/LINQ操作示例 |
|
||||||
|
|
||||||
|
### FAQ
|
||||||
|
| 文件 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `references/faq.md` | 常见问题 |
|
||||||
|
| `references/validate.md` | 参数校验 |
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. **语法限制**:magic-script 不支持 ES6 默认参数语法 `excludeValue = null`,需用 `if (excludeValue === undefined)` 判断;不支持 `new Set()`,需用数组替代
|
||||||
|
|
||||||
|
2. **数组方法**:不支持传统 `for` 循环,需用 `for (value in list)` 或 `for (index, value in list)`;**注意** Collection 扩展提供了 `reduce` 方法用于归约操作
|
||||||
|
|
||||||
|
3. **方法命名**:遍历集合用 `each` 而不是 `forEach`;获取长度用 `size()` 而不是 `length`;判断Map键用 `containsKey()` 而不是 `hasOwnProperty()`
|
||||||
|
|
||||||
|
4. **SQL参数**:`#{}` 防注入占位符用于普通参数,`${}` 字符串拼接用于动态表名/列名/排序字段(存在注入风险)
|
||||||
|
|
||||||
|
5. **类型转换**:`::type` 语法用于类型转换,如 `'123'::int`,转换失败可指定默认值 `'abc'::int(0)`
|
||||||
|
|
||||||
|
6. **获取请求参数**:
|
||||||
|
- URL参数:直接使用变量名 `name`
|
||||||
|
- 表单参数:直接使用变量名 `name`
|
||||||
|
- Header参数:`header.xxx`
|
||||||
|
- Body参数:`body.xxx`
|
||||||
|
- Path参数:`path.xxx` 或直接使用变量名
|
||||||
|
- Cookie参数:`cookie.xxx`
|
||||||
|
- Session参数:`session.xxx`
|
||||||
|
|
||||||
|
7. **循环拼接参数**:`in (#{ids})` 语法会自动对集合参数展开
|
||||||
|
|
||||||
|
8. **多数据源**:使用 `db.slave.select(...)` 格式切换数据源
|
||||||
|
|
||||||
|
9. **SQL缓存**:`db.cache("cacheName", ttl).select(...)` 使用缓存
|
||||||
|
|
||||||
|
10. **事务操作**:
|
||||||
|
- 自动事务:`db.transaction(()=>{...})`
|
||||||
|
- 手动事务:`var tx = db.transaction(); tx.commit(); tx.rollback();`
|
||||||
63
magic-script-skill/references/aggregation.md
Normal file
63
magic-script-skill/references/aggregation.md
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
# 聚合函数
|
||||||
|
|
||||||
|
## count
|
||||||
|
- 入参:`target`:`Object`
|
||||||
|
- 返回值:`int`
|
||||||
|
- 函数说明:计算集合大小
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,2,3,4,5]
|
||||||
|
return count(list); // 5
|
||||||
|
```
|
||||||
|
|
||||||
|
## sum
|
||||||
|
- 入参:`target`:`Object`
|
||||||
|
- 返回值:`Number`
|
||||||
|
- 函数说明:对集合进行求和
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,2,3,4,5]
|
||||||
|
return sum(list); // 15
|
||||||
|
```
|
||||||
|
|
||||||
|
## max
|
||||||
|
- 入参:`target`:`Object`
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:求集合最大值
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,2,3,4,5]
|
||||||
|
return max(list); // 5
|
||||||
|
```
|
||||||
|
|
||||||
|
## min
|
||||||
|
- 入参:`target`:`Object`
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:求集合最小值
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,2,3,4,5]
|
||||||
|
return min(list); // 1
|
||||||
|
```
|
||||||
|
|
||||||
|
## avg
|
||||||
|
- 入参:`target`:`Object`
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:求集合平均值
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,2,3,4,5]
|
||||||
|
return avg(list); // 3
|
||||||
|
```
|
||||||
|
|
||||||
|
## group_concat
|
||||||
|
- 入参:`target`:`Object`
|
||||||
|
- 入参:`separator`:`String` 分隔符,可省略
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:将集合拼接起来
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,2,3,4,5]
|
||||||
|
return group_concat(list); // "1,2,3,4,5"
|
||||||
|
// return group_concat(list,'|'); // "1|2|3|4|5"
|
||||||
|
```
|
||||||
128
magic-script-skill/references/api-integration.md
Normal file
128
magic-script-skill/references/api-integration.md
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
# Java调用接口
|
||||||
|
|
||||||
|
## 调用接口
|
||||||
|
```java
|
||||||
|
@Autowired
|
||||||
|
MagicAPIService service;
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
// 注入变量信息
|
||||||
|
params.put("id", 123);
|
||||||
|
// 内部调用接口不包含code以及message信息,同时也不走拦截器。
|
||||||
|
Object value = service.execute("GET", "/hello", params);
|
||||||
|
// 内部调用接口包含code以及message信息,同时也不走拦截器。
|
||||||
|
// Object value = service.call("GET", "/hello", params);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 调用函数
|
||||||
|
```java
|
||||||
|
@Autowired
|
||||||
|
MagicAPIService service;
|
||||||
|
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
// 注入变量信息
|
||||||
|
params.put("a", 1);
|
||||||
|
params.put("b", 1);
|
||||||
|
// 调用函数
|
||||||
|
Object value = service.invoke("/test/add", params);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 保存资源
|
||||||
|
```java
|
||||||
|
@Autowired
|
||||||
|
MagicResourceService service;
|
||||||
|
// 保存分组信息
|
||||||
|
service.saveGroup(group);
|
||||||
|
// 保存接口(ApiInfo)、函数(FunctionInfo)、数据源(DataSourceInfo)
|
||||||
|
service.saveFile(apiInfo);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 删除资源
|
||||||
|
```java
|
||||||
|
@Autowired
|
||||||
|
MagicResourceService service;
|
||||||
|
// 删除分组或文件
|
||||||
|
service.delete(id);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 资源列表
|
||||||
|
```java
|
||||||
|
@Autowired
|
||||||
|
MagicResourceService service;
|
||||||
|
// 获取分组下的所有文件
|
||||||
|
service.listFiles(groupId);
|
||||||
|
// 获取接口(api)、函数(function)、数据源(datasource)列表
|
||||||
|
service.files(type);
|
||||||
|
// 获取接口(api)、函数(function)、数据源(datasource)树结构
|
||||||
|
service.tree(type);
|
||||||
|
// 获取全部资源的树结构
|
||||||
|
service.tree();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 其它API
|
||||||
|
|
||||||
|
除了以上列举的`API`以外 `MagicAPIService`还有:
|
||||||
|
|
||||||
|
```java
|
||||||
|
/**
|
||||||
|
* 上传
|
||||||
|
*/
|
||||||
|
boolean upload(InputStream inputStream, String mode) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载
|
||||||
|
*/
|
||||||
|
void download(String groupId, List<SelectedResource> resources, OutputStream os) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 推送
|
||||||
|
*/
|
||||||
|
JsonBean<?> push(String target, String secretKey, String mode, List<SelectedResource> resources);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理刷新通知
|
||||||
|
*/
|
||||||
|
boolean processNotify(MagicNotify magicNotify);
|
||||||
|
```
|
||||||
|
|
||||||
|
`MagicResourceService` 还有以下方法:
|
||||||
|
|
||||||
|
```java
|
||||||
|
/**
|
||||||
|
* 刷新缓存
|
||||||
|
*/
|
||||||
|
void refresh();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移动
|
||||||
|
* @param src 源ID
|
||||||
|
* @param groupId 目标分组
|
||||||
|
*/
|
||||||
|
boolean move(String src, String groupId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制分组
|
||||||
|
* @param src 源ID
|
||||||
|
* @param target 目标分组
|
||||||
|
*/
|
||||||
|
String copyGroup(String src, String target);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件详情
|
||||||
|
*/
|
||||||
|
<T extends MagicEntity> T file(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分组详情
|
||||||
|
*/
|
||||||
|
Group getGroup(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取完整分组路径
|
||||||
|
*/
|
||||||
|
String getGroupPath(String groupId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取完整分组名称
|
||||||
|
*/
|
||||||
|
String getGroupName(String groupId);
|
||||||
|
```
|
||||||
75
magic-script-skill/references/array-functions.md
Normal file
75
magic-script-skill/references/array-functions.md
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
# 数组函数
|
||||||
|
|
||||||
|
## new_int_array
|
||||||
|
- 入参:`size`:`int` 数组长度
|
||||||
|
- 函数说明,创建`int`类型的数组
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return new_int_array(1); // [0]
|
||||||
|
```
|
||||||
|
|
||||||
|
## new_long_array
|
||||||
|
- 入参:`size`:`int` 数组长度
|
||||||
|
- 函数说明,创建`long`类型的数组
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return new_long_array(1); // [0]
|
||||||
|
```
|
||||||
|
|
||||||
|
## new_double_array
|
||||||
|
- 入参:`size`:`int` 数组长度
|
||||||
|
- 函数说明,创建`double`类型的数组
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return new_double_array(1); // [0.0]
|
||||||
|
```
|
||||||
|
|
||||||
|
## new_float_array
|
||||||
|
- 入参:`size`:`int` 数组长度
|
||||||
|
- 函数说明,创建`float`类型的数组
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return new_float_array(1); // [0.0]
|
||||||
|
```
|
||||||
|
|
||||||
|
## new_short_array
|
||||||
|
- 入参:`size`:`int` 数组长度
|
||||||
|
- 函数说明,创建`short`类型的数组
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return new_short_array(1); // [0]
|
||||||
|
```
|
||||||
|
|
||||||
|
## new_byte_array
|
||||||
|
- 入参:`size`:`int` 数组长度
|
||||||
|
- 函数说明,创建`byte`类型的数组
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return new_byte_array(1); // [0]
|
||||||
|
```
|
||||||
|
|
||||||
|
## new_boolean_array
|
||||||
|
- 入参:`size`:`int` 数组长度
|
||||||
|
- 函数说明,创建`boolean`类型的数组
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return new_boolean_array(1); // [false]
|
||||||
|
```
|
||||||
|
|
||||||
|
## new_char_array
|
||||||
|
- 入参:`size`:`int` 数组长度
|
||||||
|
- 函数说明,创建`char`类型的数组
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return new_char_array(1); // ['\0']
|
||||||
|
```
|
||||||
|
|
||||||
|
## new_array
|
||||||
|
- 入参:`Class`:类型
|
||||||
|
- 入参:`size`:`int` 数组长度
|
||||||
|
- 函数说明,创建`Object`类型的数组
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return new_array(1); // [null] // Object 类型的数组
|
||||||
|
return new_array(String.class, 1); // [null] String类型的数组
|
||||||
|
```
|
||||||
25
magic-script-skill/references/class-extensions.md
Normal file
25
magic-script-skill/references/class-extensions.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# Class扩展方法
|
||||||
|
|
||||||
|
## newInstance
|
||||||
|
- 入参:`values`:`Object` 可变参数,构造函数的参数
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:将`Class`实例化
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import 'java.text.SimpleDateFormat' as SimpleDateFormat;
|
||||||
|
return SimpleDateFormat.newInstance('yyyy-MM-dd HH:mm:ss');
|
||||||
|
//其实可以简写成 new SimpleDateFormat('yyyy-MM-dd HH:mm:ss'); //这是一个语法糖
|
||||||
|
```
|
||||||
|
|
||||||
|
## 获取类名称
|
||||||
|
支持以下方法
|
||||||
|
- `getName` - 获取完整类名
|
||||||
|
- `getSimpleName` - 获取简单类名
|
||||||
|
- `getCanonicalName` - 获取规范类名
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import 'java.text.SimpleDateFormat' as SimpleDateFormat;
|
||||||
|
println(SimpleDateFormat.getName()); // java.text.SimpleDateFormat
|
||||||
|
println(SimpleDateFormat.getSimpleName()); // SimpleDateFormat
|
||||||
|
println(SimpleDateFormat.getCanonicalName()); // java.text.SimpleDateFormat
|
||||||
|
```
|
||||||
304
magic-script-skill/references/collection-extensions.md
Normal file
304
magic-script-skill/references/collection-extensions.md
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
# 数组&集合扩展方法
|
||||||
|
|
||||||
|
为`Collection`,`Iterator`,`Enumeration`,`Object[]` 添加的扩展方法
|
||||||
|
|
||||||
|
## map
|
||||||
|
- 入参:`function`:`Function` 接收一个`Lambda`表达式
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:将集合进行循环转换
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,2,3,4,5];
|
||||||
|
return list.map(e=>e+1); //返回[2,3,4,5,6]
|
||||||
|
```
|
||||||
|
|
||||||
|
## filter
|
||||||
|
- 入参:`function`:`Function` 接收一个`Lambda`表达式
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:将集合进行过滤
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,2,3,4,5];
|
||||||
|
return list.filter(e=>e>3); //返回[4,5]
|
||||||
|
return list.filter((item,index)=>index>1); //返回[3,4,5]
|
||||||
|
```
|
||||||
|
|
||||||
|
## each
|
||||||
|
- 入参:`function`:`Function` 接收一个`Lambda`表达式
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:循环处理
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [{name : '小明'},{name : '小花'}];
|
||||||
|
return list.each(item=>item.put('age',18)); //循环添加age属性
|
||||||
|
```
|
||||||
|
|
||||||
|
## sort
|
||||||
|
- 入参:`function`:`Function` 接收一个`Lambda`表达式
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:对集合进行排序
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,5,2,3,6];
|
||||||
|
return list.sort((a,b)=>a-b);
|
||||||
|
```
|
||||||
|
|
||||||
|
## first
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:返回集合的第一项,集合为空时返回`null`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,2,3,4,5]
|
||||||
|
return list.first(); // 1
|
||||||
|
```
|
||||||
|
|
||||||
|
## last
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:返回集合的最后一项,集合为空时返回`null`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,2,3,4,5]
|
||||||
|
return list.last(); // 5
|
||||||
|
```
|
||||||
|
|
||||||
|
## reserve
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:对集合进行反转操作
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,5,2,3,6];
|
||||||
|
return list.reserve();
|
||||||
|
```
|
||||||
|
|
||||||
|
## join(拼接)
|
||||||
|
- 入参:`separator` : `String` 分隔符
|
||||||
|
- 返回值:`String`
|
||||||
|
- 函数说明:对集合进行拼接操作
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,5,2,3,6];
|
||||||
|
return list.join('-'); // 1-5-2-3-6
|
||||||
|
```
|
||||||
|
|
||||||
|
## shuffle
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:对集合进行打乱处理
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,5,2,3,6];
|
||||||
|
return list.shuffle();
|
||||||
|
```
|
||||||
|
|
||||||
|
## max
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:取出集合最大值,如果找不到返回null
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,6,8,9,18,12];
|
||||||
|
return list.max(); // 18
|
||||||
|
```
|
||||||
|
|
||||||
|
## min
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:取出集合最小值,如果找不到返回null
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [6,1,8,9,18,12];
|
||||||
|
return list.min(); // 1
|
||||||
|
```
|
||||||
|
|
||||||
|
## sum
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:累加求和,计算不出返回0.0
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,2,3,4];
|
||||||
|
return list.sum(); // 10
|
||||||
|
```
|
||||||
|
|
||||||
|
## avg
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:计算平均值,计算不出返回null
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1,2,3,4];
|
||||||
|
return list.avg(); // 2.5
|
||||||
|
```
|
||||||
|
|
||||||
|
## group
|
||||||
|
- 入参:`condition` : `Function` 分组条件
|
||||||
|
- 入参:`mapping` : `Function` 结果映射(省略时不做映射返回List)
|
||||||
|
- 返回值:`Map<Object, List<Object>>`或`Map<Object, Object>`
|
||||||
|
- 函数说明:分组
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var result = [
|
||||||
|
{ xxx : 1, yyy : 2, value : 11},
|
||||||
|
{ xxx : 1, yyy : 2, value : 22},
|
||||||
|
{ xxx : 2, yyy : 2, value : 33}
|
||||||
|
];
|
||||||
|
|
||||||
|
return result.group(item=>item.xxx + '_' + item.yyy)
|
||||||
|
// 结果:{"1_2": [{...}, {...}], "2_2": [{...}]}
|
||||||
|
```
|
||||||
|
|
||||||
|
## join(关联)
|
||||||
|
- 入参:`target` : `Object` 关联的集合
|
||||||
|
- 入参:`condition` : `Function` 关联条件
|
||||||
|
- 入参:`mapping` : `Function` 结果映射
|
||||||
|
- 返回值:`List<Object>`
|
||||||
|
- 函数说明:将两个集合关联起来
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var year2019 = [
|
||||||
|
{ "pt":2019, "item_code":"code_1", "sum_price":2234 },
|
||||||
|
{ "pt":2019, "item_code":"code_2", "sum_price":234 }
|
||||||
|
];
|
||||||
|
var year2018 = [
|
||||||
|
{ "pt":2018, "item_code":"code_1", "sum_price":1234.0 }
|
||||||
|
];
|
||||||
|
return year2019.join(year2018, (left, right) => left.item_code == right.item_code, (left, right) => {
|
||||||
|
'年份' : left.pt,
|
||||||
|
'编号' : left.item_code,
|
||||||
|
'今年' : left.sum_price,
|
||||||
|
'去年' : right == null ? 'unknow' : right.sum_price
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## asBean(转为Java对象)
|
||||||
|
- 入参:`target` : `Class<?>` 目标类型
|
||||||
|
- 返回值:`List<?>`
|
||||||
|
- 函数说明:将`List<Object>` 转为目标`List`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import 'org.ssssssss.script.functions.User' as User;
|
||||||
|
var userList = [{
|
||||||
|
age : 18,
|
||||||
|
weight : 121,
|
||||||
|
money : 123456789L,
|
||||||
|
name : '法外狂徒'
|
||||||
|
}]
|
||||||
|
return userList.asBean(User.class);
|
||||||
|
```
|
||||||
|
|
||||||
|
## every
|
||||||
|
- 入参:`condition` : `Function` 判断条件
|
||||||
|
- 返回值:`boolean`
|
||||||
|
- 函数说明:判断集合是否都符合条件
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var vals = [1, 2, 3, 4, 5, 6, 7];
|
||||||
|
return vals.every(e => e > 0); // true
|
||||||
|
```
|
||||||
|
|
||||||
|
## some
|
||||||
|
- 入参:`condition` : `Function` 判断条件
|
||||||
|
- 返回值:`boolean`
|
||||||
|
- 函数说明:判断集合是否有符合条件的
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var vals = [1, 2, 3, 4, 5, 6, 7];
|
||||||
|
return vals.some(e => e == 0); // false
|
||||||
|
```
|
||||||
|
|
||||||
|
## reduce
|
||||||
|
- 入参:`function` : `Function` 计算函数
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:循环集合通过给定的计算函数返回一个新值
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var vals = [1, 2, 3];
|
||||||
|
return vals.reduce((sum, val) => sum + val); // 6
|
||||||
|
```
|
||||||
|
|
||||||
|
## find
|
||||||
|
- 入参:`function`:`Function` 查找函数
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:循环集合查找符合条件的对象
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [{name: 'A'}, {name:'B'}]
|
||||||
|
return list.find(it => it.name == 'A'); // {name: 'A'}
|
||||||
|
```
|
||||||
|
|
||||||
|
## findIndex
|
||||||
|
- 入参:`function`:`Function` 查找函数
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:循环集合查找符合条件的对象位置
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [{name: 'A'}, {name: 'B'}]
|
||||||
|
return list.findIndex(it => it.name == 'A'); // 0
|
||||||
|
```
|
||||||
|
|
||||||
|
## concat
|
||||||
|
- 入参:`Object`,要连接的集合对象,可写多个
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:拼接一个或多个集合,返回新的集合
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [1];
|
||||||
|
return [1].concat([2]); // [1,2] list不变
|
||||||
|
return [1].concat([2],[3, 4]); // [1, 2, 3, 4] list不变
|
||||||
|
```
|
||||||
|
|
||||||
|
## toMap
|
||||||
|
- 入参:`mappingKey`:`Function`,key映射方法
|
||||||
|
- 入参:`mappingValue`:`Function`,value映射方法,可省略,默认为本身
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var list = [
|
||||||
|
{id : 1, name: 'A'},
|
||||||
|
{id : 2, name: 'B'},
|
||||||
|
{id : 3, name: 'C'},
|
||||||
|
]
|
||||||
|
return list.toMap(k => k.id, v => v.name) // {1: 'A', 2: 'B', 3: 'C'}
|
||||||
|
```
|
||||||
|
|
||||||
|
## skip
|
||||||
|
- 入参:`value` : `int` 跳过的数量
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:跳过指定个数截取集合
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var vals = [1, 2, 3, 4];
|
||||||
|
return vals.skip(2); // [3, 4]
|
||||||
|
```
|
||||||
|
|
||||||
|
## limit
|
||||||
|
- 入参:`value` : `int` 限制的数量
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:取指定个数的集合
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var vals = [1, 2, 3, 4];
|
||||||
|
return vals.limit(3); // [1, 2, 3]
|
||||||
|
```
|
||||||
|
|
||||||
|
## findNotNull
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:找到第一个不为`null`的值
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var vals = [null, null, 3, null];
|
||||||
|
return vals.findNotNull(); // 3
|
||||||
|
```
|
||||||
|
|
||||||
|
## distinct
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:去掉重复元素
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var arr = [1, 2, 2, 3];
|
||||||
|
return arr.distinct(); // [1, 2, 3]
|
||||||
|
```
|
||||||
|
|
||||||
|
## distinct(func)
|
||||||
|
- 入参: 映射函数, 形如`e -> e.id`
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:根据函数返回值去重,去掉重复元素
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var arr = [{id: 1, name: "xiaodong"}, {id:1, name: "magic-api"}];
|
||||||
|
return arr.distinct(e => e.id); // [{id: 1, name: "xiaodong"}]
|
||||||
|
```
|
||||||
11
magic-script-skill/references/date-extensions.md
Normal file
11
magic-script-skill/references/date-extensions.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Date扩展方法
|
||||||
|
|
||||||
|
## format
|
||||||
|
- 入参:`pattern`:`String` 格式
|
||||||
|
- 返回值:`String`
|
||||||
|
- 函数说明:将日期格式化
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var date = new Date();
|
||||||
|
return date.format('yyyy-MM-dd'); // 2020-01-01
|
||||||
|
```
|
||||||
36
magic-script-skill/references/date-functions.md
Normal file
36
magic-script-skill/references/date-functions.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# 日期函数
|
||||||
|
|
||||||
|
## date_format
|
||||||
|
- 入参:`target`:`Date` 日期
|
||||||
|
- 入参:`pattern`:`String` 格式
|
||||||
|
- 返回值:`String`
|
||||||
|
- 函数说明:日期格式化
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return date_format(new Date()); // 2020-01-01 20:30:30
|
||||||
|
// return date_format(new Date(),'yyyy-MM-dd'); // 2020-01-01
|
||||||
|
```
|
||||||
|
|
||||||
|
## now
|
||||||
|
- 返回值:`Date`
|
||||||
|
- 函数说明:返回当前日期
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return now(); // 等同于 new Date();
|
||||||
|
```
|
||||||
|
|
||||||
|
## current_timestamp_millis
|
||||||
|
- 返回值:`long`
|
||||||
|
- 函数说明:取当前时间戳(毫秒)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return current_timestamp_millis(); // 等同于 System.currentTimeMillis();
|
||||||
|
```
|
||||||
|
|
||||||
|
## current_timestamp
|
||||||
|
- 返回值:`long`
|
||||||
|
- 函数说明:取当前时间戳(秒)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return current_timestamp(); // 等同于 current_timestamp_millis() / 1000;
|
||||||
|
```
|
||||||
22
magic-script-skill/references/db-cache.md
Normal file
22
magic-script-skill/references/db-cache.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# 缓存操作
|
||||||
|
|
||||||
|
## cache
|
||||||
|
- 入参:`cacheName`:`String`
|
||||||
|
- 入参:`ttl`:`long` 缓存有效期,单位毫秒,可省略,默认为配置的值
|
||||||
|
- 返回值:`db` //返回当前实例,即可以链式调用
|
||||||
|
- 函数说明:使用缓存
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// 使用缓存名为user的查询
|
||||||
|
return db.cache('user').select('select * from sys_user');
|
||||||
|
```
|
||||||
|
|
||||||
|
## deleteCache
|
||||||
|
- 入参:`cacheName`:`String`
|
||||||
|
- 返回值:`db` //返回当前实例,即可以链式调用
|
||||||
|
- 函数说明:删除名为`cacheName`的缓存
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// 删除名为user的缓存
|
||||||
|
db.deleteCache('user');
|
||||||
|
```
|
||||||
63
magic-script-skill/references/db-query.md
Normal file
63
magic-script-skill/references/db-query.md
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
# 数据库查询
|
||||||
|
|
||||||
|
db模块是默认引入的模块,无需import。
|
||||||
|
|
||||||
|
## select
|
||||||
|
- 入参:`sql`:`String`
|
||||||
|
- 返回值:`List<Map<String,Object>>`
|
||||||
|
- 函数说明:查询`List`结果
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return db.select('select * from sys_user');
|
||||||
|
```
|
||||||
|
|
||||||
|
## selectInt
|
||||||
|
- 入参:`sql`:`String`
|
||||||
|
- 返回值:`Integer`
|
||||||
|
- 函数说明:查询`int`结果
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// 需要保证结果返回一行一列
|
||||||
|
return db.selectInt('select count(*) from sys_user');
|
||||||
|
```
|
||||||
|
|
||||||
|
## selectOne
|
||||||
|
- 入参:`sql`:`String`
|
||||||
|
- 返回值:`Map<String,Object>`
|
||||||
|
- 函数说明:查询单个对象
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return db.selectOne('select * from sys_user limit 1');
|
||||||
|
```
|
||||||
|
|
||||||
|
## selectValue
|
||||||
|
- 入参:`sql`:`String`
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:查询单个值
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
//需要保证结果返回一行一列
|
||||||
|
return db.selectValue('select user_name from sys_user limit 1');
|
||||||
|
```
|
||||||
|
|
||||||
|
## page
|
||||||
|
- 入参:`sql`:`String`
|
||||||
|
- 入参:`limit` : `long` 可省略
|
||||||
|
- 入参:`offset` : `long` 可省略
|
||||||
|
- 返回值:`Object` 默认返回为Object,如果自定义了分页结果,则返回自定义结果
|
||||||
|
- 函数说明:分页查询
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return db.page('select * from sys_user');
|
||||||
|
```
|
||||||
|
|
||||||
|
## 列名转换
|
||||||
|
- normal 列名保持原样
|
||||||
|
- camel 列名使用驼峰命名
|
||||||
|
- pascal 列名使用帕斯卡命名
|
||||||
|
- upper 列名保持全大写
|
||||||
|
- lower 列名保持全小写
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return db.camel().select('select * from sys_user');
|
||||||
|
```
|
||||||
23
magic-script-skill/references/db-transaction.md
Normal file
23
magic-script-skill/references/db-transaction.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# 事务操作
|
||||||
|
|
||||||
|
## 自动事务
|
||||||
|
```javascript
|
||||||
|
var val = db.transaction(()=>{
|
||||||
|
var v1 = db.update('...');
|
||||||
|
var v2 = db.update('....');
|
||||||
|
return v2;
|
||||||
|
});
|
||||||
|
return val;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 手动事务
|
||||||
|
```javascript
|
||||||
|
var tx = db.transaction(); //开启事务
|
||||||
|
try{
|
||||||
|
var value = db.update('...');
|
||||||
|
tx.commit(); // 提交事务
|
||||||
|
return value;
|
||||||
|
}catch(e){
|
||||||
|
tx.rollback(); // 回滚事务
|
||||||
|
}
|
||||||
|
```
|
||||||
49
magic-script-skill/references/db-update.md
Normal file
49
magic-script-skill/references/db-update.md
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# 数据库增删改
|
||||||
|
|
||||||
|
## update
|
||||||
|
- 入参:`sql`:`String`
|
||||||
|
- 返回值:`Integer`
|
||||||
|
- 函数说明:执行增删改操作
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return db.update('delete from sys_user');
|
||||||
|
```
|
||||||
|
|
||||||
|
## insert
|
||||||
|
- 入参:`sql`:`String`
|
||||||
|
- 入参:`id`:`String`,主键列,可空,如无特殊情况不需要传入
|
||||||
|
- 返回值: `Object`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return db.insert("insert into sys_user(username,password) values('admin','admin)");
|
||||||
|
```
|
||||||
|
|
||||||
|
## call
|
||||||
|
- 入参:`sql`: `String`
|
||||||
|
- 返回值:`Map<String,Object>`
|
||||||
|
- 函数说明:调用存储过程
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// 入参格式: #{参数名}
|
||||||
|
// 出参格式: @{参数名, java.sql.Types的类型字符串}
|
||||||
|
// 出入参格式:@{参数名(值、变量、表达式), java.sql.Types的类型字符串}
|
||||||
|
var cs1 = body.cs1;
|
||||||
|
var cs2 = body.cs2;
|
||||||
|
return db.call("""
|
||||||
|
call test(#{cs1}, @{height(cs2), INTEGER}, @{v_area, VARCHAR})
|
||||||
|
""")
|
||||||
|
// 返回:{height: 10, v_area: "16.85"}
|
||||||
|
```
|
||||||
|
|
||||||
|
## batchUpdate
|
||||||
|
- 入参:`sql`:`String`
|
||||||
|
- 入参:`batchArgs`:`List<Object[]>`数据,占位符和数组下标对应
|
||||||
|
- 返回值: `int`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return db.batchUpdate("""
|
||||||
|
update sys_dict set is_del = ? where is_del = ?
|
||||||
|
""", [
|
||||||
|
["1", "0"].toArray()
|
||||||
|
])
|
||||||
|
```
|
||||||
18
magic-script-skill/references/env-module.md
Normal file
18
magic-script-skill/references/env-module.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# 环境配置模块
|
||||||
|
|
||||||
|
## 引用模块
|
||||||
|
```javascript
|
||||||
|
import env;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用
|
||||||
|
```javascript
|
||||||
|
import env;
|
||||||
|
return env.get('server.port')
|
||||||
|
```
|
||||||
|
|
||||||
|
## get
|
||||||
|
- 入参:`key`:`String` 配置项
|
||||||
|
- 入参:`defaultValue`:`String` 默认值,可省略
|
||||||
|
- 返回值:`String`
|
||||||
|
- 函数说明:获取`Spring`配置项
|
||||||
177
magic-script-skill/references/faq.md
Normal file
177
magic-script-skill/references/faq.md
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
# 常见问题
|
||||||
|
|
||||||
|
## 如何配置JSON日期的格式
|
||||||
|
使用`Jackson`的配置如下(`Spring Boot`默认使用`Jackson`):
|
||||||
|
```yaml
|
||||||
|
spring:
|
||||||
|
jackson:
|
||||||
|
time-zone: GMT+8
|
||||||
|
date-format: yyyy-MM-dd HH:mm:ss
|
||||||
|
```
|
||||||
|
|
||||||
|
## 出现找不到db模块的错误
|
||||||
|
目前已知两种情况:
|
||||||
|
- 未配置数据源
|
||||||
|
- 未引用`spring-boot-starter-jdbc`
|
||||||
|
|
||||||
|
## 如何获取RequestBody中的参数
|
||||||
|
脚本中使用`body.xxx`获取`RequestBody`中的参数
|
||||||
|
SQL中使用`#{body.xxx}`或`${body.xxx}`获取`RequestBody`中的参数
|
||||||
|
|
||||||
|
## 如何获取Header中的参数
|
||||||
|
脚本中使用`header.xxx`获取`Header`中的参数
|
||||||
|
SQL中使用`#{header.xxx}`或`${header.xxx}`获取`Header`中的参数
|
||||||
|
|
||||||
|
## 如何获取Cookie中的参数
|
||||||
|
脚本使用`cookie.xxx`获取`Cookie`中的参数
|
||||||
|
SQL中使用`#{cookie.xxx}`或`${cookie.xxx}`获取`Cookie`中的参数
|
||||||
|
|
||||||
|
## 如何获取Session中的参数
|
||||||
|
脚本中使用`session.xxx`获取`Session`中的参数
|
||||||
|
SQL中使用`#{session.xxx}`获取`Session`中的参数
|
||||||
|
|
||||||
|
## 如何获取PathVariable中的参数
|
||||||
|
脚本中使用`PathVariableName`或`path.xxxx`获取`PathVariable`中的参数
|
||||||
|
SQL中使用`#{PathVariableName}`或`#{path.xxx}`获取`PathVariable`中的参数
|
||||||
|
|
||||||
|
## 如何获取上传的文件
|
||||||
|
利用Request模块
|
||||||
|
```javascript
|
||||||
|
import request;
|
||||||
|
request.getFile('name');
|
||||||
|
```
|
||||||
|
|
||||||
|
## 如何获取提交的数组参数
|
||||||
|
利用Request模块
|
||||||
|
```javascript
|
||||||
|
import request;
|
||||||
|
return request.getValues('name');
|
||||||
|
```
|
||||||
|
|
||||||
|
## 如何给接口添加权限
|
||||||
|
|
||||||
|
一般情况采用`拦截器`实现。在`接口选项`中配置`permisson`或`role`或自定义选项,随后在拦截器中实现:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Component
|
||||||
|
@Order(1)
|
||||||
|
public class PermissionInterceptor implements RequestInterceptor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object preHandle(ApiInfo info, MagicScriptContext context, MagicHttpServletRequest request, MagicHttpServletResponse response) {
|
||||||
|
String permissionCode = info.getOptionValue(Options.PERMISSION);
|
||||||
|
// 执行自己的代码逻辑判断是否有权限
|
||||||
|
if(无权限){
|
||||||
|
return new JsonBean<>(403,"无权访问");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 如何给UI添加权限
|
||||||
|
|
||||||
|
请参考[自定义UI鉴权](https://www.ssssssss.org/magic-api/pages/security/operation/)
|
||||||
|
|
||||||
|
## ${}和#{}的区别
|
||||||
|
主要区别在于`${}`用于拼接SQL(会产生SQL注入问题),`#{}`会替换成占位符(不会产生SQL注入问题),这里的区别与`Mybatis`一致
|
||||||
|
|
||||||
|
## 如何循环拼接参数
|
||||||
|
|
||||||
|
两种办法:
|
||||||
|
- `in (#{ids})`的语法会自动对集合参数展开
|
||||||
|
```javascript
|
||||||
|
var ids = [1,2,3,4,5,6];
|
||||||
|
return db.select('select * from sys_user where id in(#{ids})');
|
||||||
|
//会自动变成select * from sys_user where id in(?,?,?,?,?,?)
|
||||||
|
```
|
||||||
|
- 循环拼接SQL
|
||||||
|
```javascript
|
||||||
|
var list = [1,2,3,4,5];
|
||||||
|
var sql = "select * from sys_user where ";
|
||||||
|
for(index,item in list){
|
||||||
|
sql = sql + 'id = #{list['+index+']}';
|
||||||
|
if(index + 1 < list.size()){
|
||||||
|
sql = sql + ' or ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return db.select(sql);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 多数据源如何配置
|
||||||
|
编写java代码如下:
|
||||||
|
```java
|
||||||
|
@Bean
|
||||||
|
public MagicDynamicDataSource magicDynamicDataSource(){
|
||||||
|
MagicDynamicDataSource dynamicDataSource = new MagicDynamicDataSource();
|
||||||
|
dynamicDataSource.setDefault(ds1);
|
||||||
|
dynamicDataSource.add("slave",ds2);
|
||||||
|
return dynamicDataSource;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
脚本中使用:
|
||||||
|
```javascript
|
||||||
|
db.select('select * from sys_user'); //使用默认数据源
|
||||||
|
db.slave.select('select * from sys_user'); //使用slave数据源
|
||||||
|
```
|
||||||
|
|
||||||
|
## SQL执行报错java.sql.SQLFeatureNotSupportedException: null
|
||||||
|
|
||||||
|
原因:druid版本过低,升级至最新版后即可。
|
||||||
|
|
||||||
|
## 如何自定义返回结果
|
||||||
|
- 通过配置文件进行配置,具体参考[spring-boot配置](https://www.ssssssss.org/magic-api/pages/config/spring-boot/)
|
||||||
|
- 通过`自定义JSON结果`,具体定义方法查看[自定义JSON结果](https://www.ssssssss.org/magic-api/pages/base/response/)
|
||||||
|
- 通过`自定义拦截器`拦截返回自己想要的格式,具体定义方法查看[自定义拦截器](https://www.ssssssss.org/magic-api/pages/senior/interceptor/)
|
||||||
|
- 通过`spring`的拦截器返回想要的格式,如`ResponseBodyAdvice`,`HandlerMethodReturnValueHandler`(这种方式目前会影响到UI,故不推荐使用)
|
||||||
|
|
||||||
|
## 页面加载缓慢
|
||||||
|
|
||||||
|
由于`monaco-editor`编辑器比较大,建议开启压缩静态资源
|
||||||
|
```yaml
|
||||||
|
server.compression.enabled=true #启用压缩
|
||||||
|
server.compression.min-response-size=256 #大于256kb时压缩
|
||||||
|
```
|
||||||
|
|
||||||
|
## 脚本内容被转义
|
||||||
|
|
||||||
|
出现这种情况,请检查自身项目是否有`XSS`一类的过滤器,需要把`UI`界面对应的后台接口排除掉即可。
|
||||||
|
|
||||||
|
## 执行测试无响应
|
||||||
|
|
||||||
|
目前已知有两种情况:
|
||||||
|
- 使用了Spring Boot 2.3.5版本,升级至2.3.6解决
|
||||||
|
- 使用了`nginx`代理,加一条配置`proxy_buffering off;`解决
|
||||||
|
|
||||||
|
## 访问UI404
|
||||||
|
|
||||||
|
- 请检查访问路径是否正确
|
||||||
|
- 请检查`magic-editor`包是否被引入
|
||||||
|
- 如果是拉源码运行,则需要编译一下前端
|
||||||
|
- 如果以上确定没问题,请检查应用中是否有关于`mvc`的配置,如果有请检查是否是`extends WebMvcConfigurationSupport`的形式,是的话,改成`implements WebMvcConfigurer`的形式
|
||||||
|
- 如以上问题均不存在,请提[ISSUE](https://gitee.com/ssssssss-team/magic-api/issues) 或加群700818216反馈
|
||||||
|
|
||||||
|
## 无法DEBUG或无法查看日志
|
||||||
|
|
||||||
|
由于`DEBUG`和日志是依赖于`WebSocket`实现的,所以需要`WebSocket`支持。
|
||||||
|
- 请检查`Web`容器是否支持`WebSocket`,如果不支持需要引入对应依赖或更换支持`WebSocket`的`Web`容器
|
||||||
|
- 请检查是否使用了`nginx`之类的代理,如果使用了,需要对配置其支持`WebSocket`,样例如下:
|
||||||
|
```nginx
|
||||||
|
location /magic/web/console {
|
||||||
|
proxy_pass http://localhost:9999;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_read_timeout 900s;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 保存图片(Blob)数据到数据库
|
||||||
|
假设将图片的二进制数据传输到body.img中, sql可以这么写
|
||||||
|
```javascript
|
||||||
|
var sql = """
|
||||||
|
insert into img_table(img)
|
||||||
|
values(#{img::sql('blob')})
|
||||||
|
""";
|
||||||
|
```
|
||||||
97
magic-script-skill/references/http-module.md
Normal file
97
magic-script-skill/references/http-module.md
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
# HTTP模块
|
||||||
|
|
||||||
|
## 模块说明
|
||||||
|
`http`模块是基于`RestTemplate`封装而来,目前只做了少量的封装。对于一些通用的配置可以使用自定义`RestTemplate`来实现
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Bean
|
||||||
|
public HttpModule magicHttpModule() {
|
||||||
|
RestTemplate template = new RestTemplate();
|
||||||
|
// 对RestTemplate进行配置.
|
||||||
|
return new HttpModule(template);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 引用模块
|
||||||
|
```javascript
|
||||||
|
import http;
|
||||||
|
```
|
||||||
|
|
||||||
|
## connect
|
||||||
|
- 入参:`url`:`string`
|
||||||
|
- 返回值:`HttpModule`
|
||||||
|
- 函数说明:创建新的http请求对象
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import http;
|
||||||
|
http.connect("http://localhost:9999/sql/select")
|
||||||
|
```
|
||||||
|
|
||||||
|
## 设置URL参数、表单参数、Header
|
||||||
|
```javascript
|
||||||
|
import http;
|
||||||
|
http.param('url_param1','url_param_value1') // 设置URL参数
|
||||||
|
.param({ // 批量设置URL参数
|
||||||
|
url_param_2 : 2,
|
||||||
|
url_param_3 : 3,
|
||||||
|
})
|
||||||
|
.data('form_param1','form_param_value1') // 设置表单参数
|
||||||
|
.data({ // 批量设置表单参数
|
||||||
|
form_param_2 : 2,
|
||||||
|
form_param_3 : 3,
|
||||||
|
})
|
||||||
|
.header('header_param1','header_param_value1') // 设置header参数
|
||||||
|
.header({ // 批量设置header参数
|
||||||
|
header_param_2 : 2,
|
||||||
|
header_param_3 : 3,
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## body
|
||||||
|
- 入参:`body`:`Object`
|
||||||
|
- 函数说明:设置请求Body
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import http;
|
||||||
|
http.connect('..').body({
|
||||||
|
id: 1,
|
||||||
|
name: 'magic-api'
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## entity
|
||||||
|
- 入参: `entity`: `HttpEntity`
|
||||||
|
- 函数说明:自定义`HttpEntity`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import http;
|
||||||
|
http.connect('..').entity(entity)
|
||||||
|
```
|
||||||
|
|
||||||
|
## contentType
|
||||||
|
- 入参: `contentType`: `String`或`MediaType`
|
||||||
|
- 函数说明:定义请求内容类型
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import http;
|
||||||
|
http.connect('..').contentType('application/json')
|
||||||
|
```
|
||||||
|
|
||||||
|
## 请求方法
|
||||||
|
- `post()` - POST请求
|
||||||
|
- `get()` - GET请求
|
||||||
|
- `delete()` - DELETE请求
|
||||||
|
- `put()` - PUT请求
|
||||||
|
- `head()` - HEAD请求
|
||||||
|
- `patch()` - PATCH请求
|
||||||
|
- `options()` - OPTIONS请求
|
||||||
|
- `trace()` - TRACE请求
|
||||||
|
|
||||||
|
## execute
|
||||||
|
- 返回值:`ResponseEntity`
|
||||||
|
- 函数说明:执行对应的请求
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import http;
|
||||||
|
return http.connect('http://localhost:9999/sql/select').post().getBody()
|
||||||
|
```
|
||||||
42
magic-script-skill/references/java-integration.md
Normal file
42
magic-script-skill/references/java-integration.md
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# 脚本调用Java
|
||||||
|
|
||||||
|
## 注入Spring Bean
|
||||||
|
```javascript
|
||||||
|
// 第一种方式
|
||||||
|
import xx.xxx.xxx.xxx.UserService; // 使用类名
|
||||||
|
return UserService.selectUserList();
|
||||||
|
|
||||||
|
// 第二种方式
|
||||||
|
import "userUservice" as userService; // 使用Bean名
|
||||||
|
return userService.selectUserList();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 调用静态方法
|
||||||
|
```javascript
|
||||||
|
import xxx.xxx.xx.xx.xx.StringUtils;
|
||||||
|
return StringUtils.isBlank("");
|
||||||
|
```
|
||||||
|
|
||||||
|
## 调用普通方法
|
||||||
|
```javascript
|
||||||
|
// 对于java.util、java.lang 包下的类,可以直接使用。
|
||||||
|
return new ArrayList();
|
||||||
|
|
||||||
|
// 对于其他类需要import
|
||||||
|
import "java.text.SimpleDateFormat";
|
||||||
|
return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
|
||||||
|
```
|
||||||
|
|
||||||
|
## 调用magic-api的接口
|
||||||
|
```javascript
|
||||||
|
// 可以在脚本中直接调用,非http方式
|
||||||
|
import "@get:/api/sys/user/list" as userList; // 导入定义的GET请求的 /api/sys/user/list 接口。
|
||||||
|
// 脚本中变量是共享给调用者的。所以无需指定参数传入。只需要在本脚本中定义该变量即可。
|
||||||
|
return userList();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 调用magic-api的函数
|
||||||
|
```javascript
|
||||||
|
import "@/common/encode/md5" as md5; // 导入页面上定义的函数信息
|
||||||
|
return md5('123456');
|
||||||
|
```
|
||||||
108
magic-script-skill/references/keywords.md
Normal file
108
magic-script-skill/references/keywords.md
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
# 关键字、运算符、数据类型
|
||||||
|
|
||||||
|
## 关键字
|
||||||
|
|
||||||
|
| 关键字 | 含义 |
|
||||||
|
|--------|------|
|
||||||
|
| var | 定义变量 |
|
||||||
|
| if | 条件语句的引导词 |
|
||||||
|
| else | 用在条件语句中,表明当条件不成立时的分支 |
|
||||||
|
| for | for循环语句 |
|
||||||
|
| in | 与for配合使用 |
|
||||||
|
| while | while循环语句 |
|
||||||
|
| continue | 执行下一次循环 |
|
||||||
|
| break | 跳出循环 |
|
||||||
|
| return | 终止当前过程的执行并正常退出到上一个执行过程中 |
|
||||||
|
| exit | 终止当前脚本,并退出返回,如`exit 200,'执行成功',[1,2,3];` |
|
||||||
|
| assert | 断言 |
|
||||||
|
| instanceof | 判断一个对象是否为一个类的实例 |
|
||||||
|
| try | 用于捕获可能发生异常的代码块 |
|
||||||
|
| catch | 与try关键字配合使用,当发生异常时执行 |
|
||||||
|
| finally | 与try关键字配合使用,finally块无论发生异常都会执行 |
|
||||||
|
| import | 导入Java类或导入已定义好的模块 |
|
||||||
|
| as | 与 import 关键字配合使用,用作将导入的 Java类或模块 命名为一个本地变量名 |
|
||||||
|
| new | 创建对象 |
|
||||||
|
| true | 基础类型之一,表示 Boolean 的:真值 |
|
||||||
|
| false | 基础类型之一,表示 Boolean 的:假值 |
|
||||||
|
| null | 基础类型之一,表示 NULL 值 |
|
||||||
|
| async | 异步调用 |
|
||||||
|
|
||||||
|
## 运算符
|
||||||
|
|
||||||
|
### 数学运算
|
||||||
|
| 运算符 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| + | 加法 |
|
||||||
|
| - | 减法 |
|
||||||
|
| * | 乘法 |
|
||||||
|
| / | 除法 |
|
||||||
|
| % | 取模 |
|
||||||
|
| ++ | 自增 |
|
||||||
|
| -- | 自减 |
|
||||||
|
| += | 加等于 |
|
||||||
|
| -= | 减等于 |
|
||||||
|
| *= | 乘等于 |
|
||||||
|
| /= | 除等于 |
|
||||||
|
| %= | 取模等于 |
|
||||||
|
|
||||||
|
### 比较运算符
|
||||||
|
| 运算符 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| < | 小于 |
|
||||||
|
| <= | 小于等于 |
|
||||||
|
| > | 大于 |
|
||||||
|
| >= | 大于等于 |
|
||||||
|
| == | 等于 |
|
||||||
|
| != | 不等于 |
|
||||||
|
| === | 等于 |
|
||||||
|
| !== | 不等于 |
|
||||||
|
|
||||||
|
### 逻辑运算符
|
||||||
|
| 运算符 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| && | 并且 |
|
||||||
|
| \|\| | 或者 |
|
||||||
|
| ! | 取反 |
|
||||||
|
|
||||||
|
### 位运算符
|
||||||
|
| 运算符 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| & | 与 |
|
||||||
|
| \| | 或 |
|
||||||
|
| ^ | 异或 |
|
||||||
|
| ~ | 取反 |
|
||||||
|
| << | 左移 |
|
||||||
|
| >> | 右移 |
|
||||||
|
| >>> | 无符号右移 |
|
||||||
|
|
||||||
|
## 数据类型
|
||||||
|
|
||||||
|
| 类型 | 写法 |
|
||||||
|
|------|------|
|
||||||
|
| byte | `123b`、`123B` |
|
||||||
|
| short | `123s`、`123S` |
|
||||||
|
| int | `123` |
|
||||||
|
| long | `123l`、`123L` |
|
||||||
|
| float | `123f`、`123F` |
|
||||||
|
| double | `123d`、`123D` |
|
||||||
|
| BigDecimal | `123m`、`123M` |
|
||||||
|
| boolean | `true`、`false` |
|
||||||
|
| string | `'hello'` 或 `"hello"` |
|
||||||
|
| string | `"""多行文本块,主要用于编写SQL"""` |
|
||||||
|
| Pattern | `/\d+/g`,`/pattern/gimuy` 用于定义正则 |
|
||||||
|
| lambda | `()=>expr`、`(param1,param2....)=>{...}` |
|
||||||
|
| list | `[1,2,3,4,5]` |
|
||||||
|
| map | `{key : value,key1 : value}` 或 `{[key] : "value"}` |
|
||||||
|
|
||||||
|
## 三元运算符
|
||||||
|
|
||||||
|
三元运算符是`if`语句的简写形式,其工作方式类似于Java中,例如`true ? "yes" : "no"`
|
||||||
|
|
||||||
|
增强的`if`和三元运算符,不再强制值必须是布尔类型,可以写`if(xxx)`的形式当`xxx`为以下情况时为`false`、其它情况为`true`:
|
||||||
|
- `null`
|
||||||
|
- 空集合
|
||||||
|
- 空Map
|
||||||
|
- 空数组
|
||||||
|
- 数值==0
|
||||||
|
- 空字符串
|
||||||
|
- `false`
|
||||||
102
magic-script-skill/references/lambda-async.md
Normal file
102
magic-script-skill/references/lambda-async.md
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
# Lambda表达式与异步调用
|
||||||
|
|
||||||
|
## Lambda表达式
|
||||||
|
|
||||||
|
### 映射(map)
|
||||||
|
```javascript
|
||||||
|
var list = [
|
||||||
|
{sex : 0,name : '小明',age : 19},
|
||||||
|
{sex : 1,name : '小花',age : 18}
|
||||||
|
];
|
||||||
|
var getAge = (age) => age > 18 ? '成人' : '未成年'
|
||||||
|
return list.map(item => {
|
||||||
|
age : getAge(item.age),
|
||||||
|
sex : item.sex == 0 ? '男' : '女',
|
||||||
|
name : item.name
|
||||||
|
});
|
||||||
|
// 结果:[{sex: "男", name: "小明", age: "成人"}, {sex: "女", name: "小花", age: "未成年"}]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 过滤(filter)
|
||||||
|
```javascript
|
||||||
|
var list = [
|
||||||
|
{sex : 0,name : '小明'},
|
||||||
|
{sex : 1,name : '小花'}
|
||||||
|
]
|
||||||
|
return list.filter(item => item.sex == 0);
|
||||||
|
// 结果:[{sex: 0, name: "小明"}]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 过滤+映射(filter + map)
|
||||||
|
```javascript
|
||||||
|
var list = [
|
||||||
|
{sex : 0,name : '小明'},
|
||||||
|
{sex : 1,name : '小花'}
|
||||||
|
]
|
||||||
|
return list.filter(item => item.sex == 0).map(item => {
|
||||||
|
sex : item.sex == 0 ? '男' : '女',
|
||||||
|
name : item.name
|
||||||
|
});
|
||||||
|
// 结果:[{sex: "男", name: "小明"}]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 分组(group)
|
||||||
|
默认聚合为List
|
||||||
|
```javascript
|
||||||
|
var result = [
|
||||||
|
{ xxx : 1, yyy : 2, value : 11},
|
||||||
|
{ xxx : 1, yyy : 2, value : 22},
|
||||||
|
{ xxx : 2, yyy : 2, value : 33}
|
||||||
|
];
|
||||||
|
|
||||||
|
return result.group(item => item.xxx + '_' + item.yyy)
|
||||||
|
// 结果:{"1_2": [{...}, {...}], "2_2": [{...}]}
|
||||||
|
```
|
||||||
|
|
||||||
|
自定义聚合对象
|
||||||
|
```javascript
|
||||||
|
return result.group(item => item.xxx + '_' + item.yyy,list => {
|
||||||
|
count : list.size(),
|
||||||
|
sum : list.map(v=>v.value).sum(),
|
||||||
|
avg : list.map(v=>v.value).avg()
|
||||||
|
})
|
||||||
|
// 结果:{"1_2": {"avg": 16.5, "count": 2, "sum": 33}, "2_2": {"avg": 33, "count": 1, "sum": 33}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 关联(join)
|
||||||
|
```javascript
|
||||||
|
var year2019 = [
|
||||||
|
{ "pt":2019, "item_code":"code_1", "sum_price":2234 },
|
||||||
|
{ "pt":2019, "item_code":"code_2", "sum_price":234 }
|
||||||
|
];
|
||||||
|
var year2018 = [
|
||||||
|
{ "pt":2018, "item_code":"code_1", "sum_price":1234.0 }
|
||||||
|
];
|
||||||
|
return year2019.join(year2018, (left, right) => left.item_code == right.item_code, (left, right) => {
|
||||||
|
'年份' : left.pt,
|
||||||
|
'编号' : left.item_code,
|
||||||
|
'今年' : left.sum_price,
|
||||||
|
'去年' : right == null ? 'unknow' : right.sum_price
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## 异步调用
|
||||||
|
|
||||||
|
### 普通方法
|
||||||
|
```javascript
|
||||||
|
// 使用async关键字,会启动一个线程去执行,返回Future
|
||||||
|
var user1 = async db.select("select * from sys_user where id = 1");
|
||||||
|
var user2 = async db.select("select * from sys_user where id = 2");
|
||||||
|
// 调用get方法表示阻塞等待获取结果
|
||||||
|
return [user1.get(),user2.get()];
|
||||||
|
```
|
||||||
|
|
||||||
|
### lambda
|
||||||
|
```javascript
|
||||||
|
var list = [];
|
||||||
|
for(index in range(1,10)){
|
||||||
|
// 当异步中使用外部变量时,为了确保线程安全的变量,可以将其放在形参中
|
||||||
|
list.add(async (index)=>db.select("select * from sys_user where id = #{index}"));
|
||||||
|
}
|
||||||
|
return list.map(item=>item.get());
|
||||||
|
```
|
||||||
76
magic-script-skill/references/linq.md
Normal file
76
magic-script-skill/references/linq.md
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# Linq
|
||||||
|
|
||||||
|
## 基本语法
|
||||||
|
```sql
|
||||||
|
select
|
||||||
|
tableAlias.*|[tableAlias.]field[ columnAlias]
|
||||||
|
[,tableAlias.field2[ columnAlias2][,…]]
|
||||||
|
from expr[,…] tableAlias
|
||||||
|
[[left ]join expr tableAlias2 on condition]
|
||||||
|
[where condition]
|
||||||
|
[group by tableAlias.field[,...]]
|
||||||
|
[having condition]
|
||||||
|
[order by tableAlias.field[asc|desc][,tableAlias.field[asc|desc]]]
|
||||||
|
[limit expr [offset expr]]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 执行步骤
|
||||||
|
- 先从`from`子句创建虚拟表VT1
|
||||||
|
- 处理`join`,创建虚拟表VT2,筛选符合条件`condition`的行加入到虚拟表VT2中
|
||||||
|
- 处理`where` 将符合`condition`的行加入虚拟表VT1中
|
||||||
|
- 处理`group by` 对虚拟表VT1、VT2进行分组操作,将符合`having condition`的值加入虚拟表VT3中
|
||||||
|
- 处理`select` 从VT3中选择指定的列,加入虚拟表VT4中
|
||||||
|
- 处理`order by` 对虚拟表VT4进行排序
|
||||||
|
- 处理`limit`
|
||||||
|
|
||||||
|
## select子句
|
||||||
|
```sql
|
||||||
|
select t.name,sum(t.score) score,t.*
|
||||||
|
```
|
||||||
|
> select 中带有聚合函数的,应该有group by语句,否则不会进行聚合处理
|
||||||
|
|
||||||
|
## from子句
|
||||||
|
```sql
|
||||||
|
-- 以下三种方式均可(别名是必须的)
|
||||||
|
from [{name: 'Gitee'},[name:'Github']] t
|
||||||
|
from results t
|
||||||
|
from {name:'Gitee'} t
|
||||||
|
```
|
||||||
|
> from 跟着的必须是`List`或者`Map`
|
||||||
|
|
||||||
|
## join子句
|
||||||
|
```sql
|
||||||
|
-- 以下三种方式均可(别名是必须的)
|
||||||
|
[left] join [{name: 'Gitee'},[name:'Github']] t1 on t1.name = t.name
|
||||||
|
[left] join results t1 on 1 = 1
|
||||||
|
[left] join {name:'Gitee'} t1 on t1.name = 'Gitee' and 1=1
|
||||||
|
```
|
||||||
|
|
||||||
|
## where子句
|
||||||
|
```sql
|
||||||
|
-- or 等价于|| and 等价于 && 可以混合使用。
|
||||||
|
where t.name = 'Gitee' or t.name = 'Github' and 1=1 && 2=2
|
||||||
|
```
|
||||||
|
|
||||||
|
## group by子句
|
||||||
|
```sql
|
||||||
|
group by t.name, t1.xxx
|
||||||
|
```
|
||||||
|
|
||||||
|
## having 子句
|
||||||
|
```sql
|
||||||
|
having count(t.name) > 1
|
||||||
|
```
|
||||||
|
|
||||||
|
## order by子句
|
||||||
|
```sql
|
||||||
|
-- asc可以不写,默认是asc
|
||||||
|
order by t.name desc,t.xxx
|
||||||
|
```
|
||||||
|
|
||||||
|
## limit 子句
|
||||||
|
```sql
|
||||||
|
limit 1 -- 固定取第一项,返回值会是对象,而非List
|
||||||
|
limit pageSize offset (page - 1) * pageSize
|
||||||
|
limit pageSize
|
||||||
|
```
|
||||||
15
magic-script-skill/references/log-module.md
Normal file
15
magic-script-skill/references/log-module.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# 日志模块
|
||||||
|
|
||||||
|
## 引用模块
|
||||||
|
```javascript
|
||||||
|
import log;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用
|
||||||
|
```javascript
|
||||||
|
import log; //org.slf4j.Logger
|
||||||
|
// 使用方法与SLF4J完全一致
|
||||||
|
log.info('Hello');
|
||||||
|
log.info('Hello {}','MagicAPI');
|
||||||
|
log.debug('test');
|
||||||
|
```
|
||||||
45
magic-script-skill/references/magic-module.md
Normal file
45
magic-script-skill/references/magic-module.md
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# Magic模块
|
||||||
|
|
||||||
|
## 引用模块
|
||||||
|
```javascript
|
||||||
|
import magic;
|
||||||
|
```
|
||||||
|
|
||||||
|
## call
|
||||||
|
- 入参:`method`:`String` 定义的请求方法
|
||||||
|
- 入参:`path`:`String` 定义的路径
|
||||||
|
- 入参:`parameters`:`Map` 变量信息
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:执行MagicAPI中的接口,返回值带code和message信息
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return magic.call('get','execute/sql',{
|
||||||
|
message : 'Hello,Magic API!' //传入参数
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## execute
|
||||||
|
- 入参:`method`:`String` 定义的请求方法
|
||||||
|
- 入参:`path`:`String` 定义的请求路径
|
||||||
|
- 入参:`parameters`:`Map` 变量信息
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:执行MagicAPI中的接口,返回原始内容,不包含code以及message信息
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return magic.execute('get','execute/sql',{
|
||||||
|
message : 'Hello,Magic API!' //传入参数
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## invoke
|
||||||
|
- 入参:`path`:`String` 函数路径
|
||||||
|
- 入参:`parameters`:`Map` 变量信息
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:执行MagicAPI中的函数
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return magic.invoke('/test/add',{
|
||||||
|
a: 1,
|
||||||
|
b: 2
|
||||||
|
})
|
||||||
|
```
|
||||||
39
magic-script-skill/references/math-functions.md
Normal file
39
magic-script-skill/references/math-functions.md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# 数学函数
|
||||||
|
|
||||||
|
## round
|
||||||
|
- 入参:`number`:`Number` 目标值
|
||||||
|
- 入参:`len`:`int` 要保留的小数位数 可省略,默认0
|
||||||
|
- 返回值:`Number`
|
||||||
|
- 函数说明:四舍五入保留N位小数
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return round(123.456d,2); //123.46
|
||||||
|
```
|
||||||
|
|
||||||
|
## floor
|
||||||
|
- 入参:`number`:`Number` 目标值
|
||||||
|
- 返回值:`Number`
|
||||||
|
- 函数说明:向下取整
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return floor(123.456d); // 123;
|
||||||
|
```
|
||||||
|
|
||||||
|
## ceil
|
||||||
|
- 入参:`number`:`Number` 目标值
|
||||||
|
- 返回值:`Number`
|
||||||
|
- 函数说明:向上取整
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return ceil(123.456d); // 124;
|
||||||
|
```
|
||||||
|
|
||||||
|
## percent
|
||||||
|
- 入参:`number`:`Number` 目标值
|
||||||
|
- 入参:`len`:`int` 要保留的小数 可省略,默认0
|
||||||
|
- 返回值:`String`
|
||||||
|
- 函数说明:将数值转为百分比
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return percent(0.1289999999,2); // "12.90%"
|
||||||
|
```
|
||||||
51
magic-script-skill/references/number-extensions.md
Normal file
51
magic-script-skill/references/number-extensions.md
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# Number扩展方法
|
||||||
|
|
||||||
|
`java.lang.Number`的扩展方法,用于数值类型的扩展
|
||||||
|
|
||||||
|
## round
|
||||||
|
- 入参:`number`:`int` 要保留的小数
|
||||||
|
- 返回值:`Number`
|
||||||
|
- 函数说明:四舍五入保留N位小数
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var value = 123.456d;
|
||||||
|
return value.round(2); //123.46
|
||||||
|
```
|
||||||
|
|
||||||
|
## toFixed
|
||||||
|
- 入参:`number`:`int` 要保留的小数
|
||||||
|
- 返回值:`String`
|
||||||
|
- 函数说明:四舍五入保留N位小数(和JS一样,强制限制位数)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var value = 123.456d;
|
||||||
|
return value.toFixed(10); // "123.4560000000"
|
||||||
|
```
|
||||||
|
|
||||||
|
## floor
|
||||||
|
- 返回值:`Number`
|
||||||
|
- 函数说明:向下取整
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var value = 123.456d;
|
||||||
|
return value.floor(); // 123;
|
||||||
|
```
|
||||||
|
|
||||||
|
## ceil
|
||||||
|
- 返回值:`Number`
|
||||||
|
- 函数说明:向上取整
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var value = 123.456d;
|
||||||
|
return value.ceil(); // 124;
|
||||||
|
```
|
||||||
|
|
||||||
|
## asPercent
|
||||||
|
- 入参:`number`:`int` 要保留的小数
|
||||||
|
- 返回值:`String`
|
||||||
|
- 函数说明:将数值转为百分比
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var value = 0.1289999999;
|
||||||
|
return value.asPercent(2); // "12.90%"
|
||||||
|
```
|
||||||
129
magic-script-skill/references/object-extensions.md
Normal file
129
magic-script-skill/references/object-extensions.md
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
# Object扩展方法
|
||||||
|
|
||||||
|
## asInt
|
||||||
|
- 入参:`defaultValue`:`int` 选填,当转换失败时返回默认值,默认为`0`
|
||||||
|
- 返回值:`int`
|
||||||
|
- 函数说明:转对象为int类型
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var obj = '123';
|
||||||
|
return obj.asInt();
|
||||||
|
//return obj.asInt(1); //转换失败时,返回1
|
||||||
|
```
|
||||||
|
|
||||||
|
## asDouble
|
||||||
|
- 入参:`defaultValue`:`double` 选填,当转换失败时返回默认值,默认为`0.0`
|
||||||
|
- 返回值:`double`
|
||||||
|
- 函数说明:转对象为`double`类型
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var obj = '123';
|
||||||
|
return obj.asDouble();
|
||||||
|
//return obj.asDouble(1.0d); //转换失败时,返回1.0d
|
||||||
|
```
|
||||||
|
|
||||||
|
## asDecimal
|
||||||
|
- 入参:`defaultValue`:`BigDecimal` 选填,当转换失败时返回默认值,默认为`null`
|
||||||
|
- 返回值:`BigDecimal`
|
||||||
|
- 函数说明:转对象为`BigDecimal`类型
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var obj = '123.456';
|
||||||
|
return obj.asDecimal();
|
||||||
|
//return obj.asDecimal(1.5m); //转换失败时,返回1.5m
|
||||||
|
```
|
||||||
|
|
||||||
|
## asFloat
|
||||||
|
- 入参:`defaultValue`:`float` 选填,当转换失败时返回默认值,默认为`0.0f`
|
||||||
|
- 返回值:`float`
|
||||||
|
- 函数说明:转对象为`float`类型
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var obj = '123';
|
||||||
|
return obj.asFloat();
|
||||||
|
//return obj.asFloat(1.0f); //转换失败时,返回1.0f
|
||||||
|
```
|
||||||
|
|
||||||
|
## asLong
|
||||||
|
- 入参:`defaultValue`:`long` 选填,当转换失败时返回默认值,默认为`0L`
|
||||||
|
- 返回值:`long`
|
||||||
|
- 函数说明:转对象为`long`类型
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var obj = '123';
|
||||||
|
return obj.asLong();
|
||||||
|
//return obj.asLong(1L); //转换失败时,返回1L
|
||||||
|
```
|
||||||
|
|
||||||
|
## asByte
|
||||||
|
- 入参:`defaultValue`:`byte` 选填,当转换失败时返回默认值,默认为`0b`
|
||||||
|
- 返回值:`byte`
|
||||||
|
- 函数说明:转对象为`byte`类型
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var obj = '123';
|
||||||
|
return obj.asByte();
|
||||||
|
//return obj.asByte(1b); //转换失败时,返回1b
|
||||||
|
```
|
||||||
|
|
||||||
|
## asShort
|
||||||
|
- 入参:`defaultValue`:`short` 选填,当转换失败时返回默认值,默认为`0s`
|
||||||
|
- 返回值:`short`
|
||||||
|
- 函数说明:转对象为`short`类型
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var obj = '123';
|
||||||
|
return obj.asShort();
|
||||||
|
//return obj.asShort(1s); //转换失败时,返回1s
|
||||||
|
```
|
||||||
|
|
||||||
|
## asDate
|
||||||
|
- 入参:`formats`:`String` 可变参数,日期格式
|
||||||
|
- 返回值:`Date`
|
||||||
|
- 函数说明:转对象为`Date`类型
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var obj = '2020-01-01 08:00:00';
|
||||||
|
return obj.asDate('yyyy-MM-dd HH:mm:ss','yyyy-MM-dd HH:mm');
|
||||||
|
```
|
||||||
|
|
||||||
|
## asString
|
||||||
|
- 入参:`defaultValue`:`String` 选填,当转换失败时返回默认值,默认为`null`
|
||||||
|
- 返回值:`String`
|
||||||
|
- 函数说明:转对象为`String`类型
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var obj = 123;
|
||||||
|
return obj.asString();
|
||||||
|
//return obj.asString("empty"); //转换失败时,返回"empty"
|
||||||
|
```
|
||||||
|
|
||||||
|
## is
|
||||||
|
- 入参:`type`:`String/Class` 判断是否该类型
|
||||||
|
- 返回值:`boolean`
|
||||||
|
- 函数说明:判断是否是指定类型
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import 'java.util.Date' as Date;
|
||||||
|
var str = 'hello,MagicAPI';
|
||||||
|
return str.is('string'); // true
|
||||||
|
return str.is('java.lang.String'); // true
|
||||||
|
return str.is('java.lang.Integer'); // false
|
||||||
|
return str.is(Date); // false
|
||||||
|
```
|
||||||
|
|
||||||
|
## 类型判断方法
|
||||||
|
- `isString()` - 判断是否是String类型
|
||||||
|
- `isInt()` - 判断是否是int类型
|
||||||
|
- `isLong()` - 判断是否是long类型
|
||||||
|
- `isDouble()` - 判断是否是double类型
|
||||||
|
- `isFloat()` - 判断是否是float类型
|
||||||
|
- `isByte()` - 判断是否是byte类型
|
||||||
|
- `isBoolean()` - 判断是否是boolean类型
|
||||||
|
- `isShort()` - 判断是否是short类型
|
||||||
|
- `isDecimal()` - 判断是否是decimal类型
|
||||||
|
- `isDate()` - 判断是否是Date类型
|
||||||
|
- `isArray()` - 判断是否是数组
|
||||||
|
- `isList()` - 判断是否是List
|
||||||
|
- `isMap()` - 判断是否是Map
|
||||||
|
- `isCollection()` - 判断是否是集合
|
||||||
55
magic-script-skill/references/other-functions.md
Normal file
55
magic-script-skill/references/other-functions.md
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# 其它函数
|
||||||
|
|
||||||
|
## print
|
||||||
|
- 入参:`target`:`Object` 要打印的对象
|
||||||
|
- 函数说明:打印
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
print('abc'); // 等同于 System.out.print("abc");
|
||||||
|
```
|
||||||
|
|
||||||
|
## println
|
||||||
|
- 入参:`target`:`Object` 要打印的对象
|
||||||
|
- 函数说明:打印并换行
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
println('abc'); // 等同于 System.out.println("abc");
|
||||||
|
```
|
||||||
|
|
||||||
|
## printf
|
||||||
|
- 入参:`format`:`String` 要打印的对象
|
||||||
|
- 入参:`target`: `Object` 参数值,可以写多个
|
||||||
|
- 函数说明:按照格式打印并换行
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
printf('%s:%s', 'a','b'); // 等同于 System.out.printf("%s:%S", "a", "b");
|
||||||
|
```
|
||||||
|
|
||||||
|
## not_null
|
||||||
|
- 入参:`target` : `Object` 判断的模板
|
||||||
|
- 返回值:`boolean`
|
||||||
|
- 函数说明:判断值不是`null`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return not_null(target); // 等同于 target != null
|
||||||
|
```
|
||||||
|
|
||||||
|
## is_null
|
||||||
|
- 入参:`target` : `Object` 判断的模板
|
||||||
|
- 返回值:`boolean`
|
||||||
|
- 函数说明:判断值是`null`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return is_null(target); // 等同于 target == null
|
||||||
|
```
|
||||||
|
|
||||||
|
## ifnull
|
||||||
|
- 入参:`target`:`Object` 判断的目标
|
||||||
|
- 入参:`trueValue`:`Object` 为空时的值
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:对空值进行判断,返回特定值
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return ifnull(null,1) // 1
|
||||||
|
// return ifnull(0,1) // 0
|
||||||
|
```
|
||||||
32
magic-script-skill/references/page.md
Normal file
32
magic-script-skill/references/page.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# 分页查询
|
||||||
|
|
||||||
|
## 自动分页
|
||||||
|
`db.page`可从形如`xxx?page=1&size=10`的url中获取分页参数。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// 自动从请求参数中获取页码(默认为page)、页大小(默认为size)
|
||||||
|
return db.page("""
|
||||||
|
select * from sys_user
|
||||||
|
""")
|
||||||
|
```
|
||||||
|
|
||||||
|
## 手动分页
|
||||||
|
可手动传入分页参数。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return db.page("""
|
||||||
|
select * from sys_user
|
||||||
|
""", 10, 20) // 跳过前20条查10条(limit, offset)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 自定义分页参数
|
||||||
|
可根据需要在自己的项目中,调整以下分页参数。
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
magic-api:
|
||||||
|
page:
|
||||||
|
size: size # 页大小的请求参数名称 缺省时为size
|
||||||
|
page: page # 页码的请求参数名称 缺省时为page
|
||||||
|
default-page: 1 # 自定义默认首页 缺省时为1
|
||||||
|
default-size: 10 # 自定义为默认页大小 缺省时为10
|
||||||
|
```
|
||||||
13
magic-script-skill/references/pattern-extensions.md
Normal file
13
magic-script-skill/references/pattern-extensions.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Pattern扩展方法
|
||||||
|
|
||||||
|
`java.util.regex.Pattern`的扩展方法
|
||||||
|
|
||||||
|
## test
|
||||||
|
- 入参:`source`:`String` 目标字符串
|
||||||
|
- 返回值:`boolean`
|
||||||
|
- 函数说明:校验文本是否符合正则
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var regx = /^\d+$/;
|
||||||
|
return regx.test('123456') // true
|
||||||
|
```
|
||||||
125
magic-script-skill/references/quick-crud.md
Normal file
125
magic-script-skill/references/quick-crud.md
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
# 增删改查
|
||||||
|
|
||||||
|
## SQL参数
|
||||||
|
|
||||||
|
### #{} 注入参数
|
||||||
|
作用和`mybatis`一致,都是将`#{}`区域替换为占位符`?`
|
||||||
|
```javascript
|
||||||
|
var id = 123;
|
||||||
|
return db.select("""
|
||||||
|
select * from sys_user where id = #{id}
|
||||||
|
""");
|
||||||
|
// 运行时生成的SQL为:select * from sys_user where id = ?
|
||||||
|
```
|
||||||
|
|
||||||
|
### ${} 拼接参数
|
||||||
|
作用和`mybatis`一致,都是将`${}`区域替换为对应的字符串
|
||||||
|
```javascript
|
||||||
|
var id = 123;
|
||||||
|
return db.select("""
|
||||||
|
select * from sys_user where id = ${id}
|
||||||
|
""");
|
||||||
|
// 运行时生成的SQL为:select * from sys_user where id = 123
|
||||||
|
```
|
||||||
|
|
||||||
|
## 动态SQL参数
|
||||||
|
通过`?{condition,expression}`来实现动态拼接`SQL`
|
||||||
|
```javascript
|
||||||
|
return db.select("select * from sys_user ?{id,where id = #{id}}");
|
||||||
|
// 当id有值时,生成SQL:select * from sys_user where id = ?
|
||||||
|
// 当id无值时,生成SQL:select * from sys_user
|
||||||
|
```
|
||||||
|
|
||||||
|
## 切换数据源
|
||||||
|
```javascript
|
||||||
|
// 从数据源key定义为slave的库中查询
|
||||||
|
return db.slave.select("""
|
||||||
|
select * from sys_user
|
||||||
|
""")
|
||||||
|
```
|
||||||
|
|
||||||
|
## SQL缓存
|
||||||
|
```javascript
|
||||||
|
// 将查询结果缓存到名为user_cache的缓存中,有效期1小时
|
||||||
|
return db.cache("user_cache", 3600 * 1000).select("""
|
||||||
|
select * from sys_user
|
||||||
|
""")
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用事务
|
||||||
|
|
||||||
|
### 自动事务
|
||||||
|
```javascript
|
||||||
|
var val = db.transaction(()=>{
|
||||||
|
var v1 = db.update('...');
|
||||||
|
var v2 = db.update('....');
|
||||||
|
return v2;
|
||||||
|
});
|
||||||
|
return val;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 手动事务
|
||||||
|
```javascript
|
||||||
|
var tx = db.transaction(); //开启事务
|
||||||
|
try{
|
||||||
|
var value = db.update('...');
|
||||||
|
tx.commit(); // 提交事务
|
||||||
|
return value;
|
||||||
|
}catch(e){
|
||||||
|
tx.rollback(); // 回滚事务
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mybatis语法支持
|
||||||
|
|
||||||
|
### if
|
||||||
|
```javascript
|
||||||
|
var sql = """
|
||||||
|
select * from test_data
|
||||||
|
where 1 = 1
|
||||||
|
<if test="id != null">
|
||||||
|
and id = #{id}
|
||||||
|
</if>
|
||||||
|
"""
|
||||||
|
return db.select(sql)
|
||||||
|
```
|
||||||
|
|
||||||
|
### where
|
||||||
|
```javascript
|
||||||
|
var sql = """
|
||||||
|
select * from test_data
|
||||||
|
<where>
|
||||||
|
<if test="id != null">
|
||||||
|
and id = #{id}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
"""
|
||||||
|
return db.select(sql)
|
||||||
|
```
|
||||||
|
|
||||||
|
### set、trim
|
||||||
|
```javascript
|
||||||
|
var sql = """
|
||||||
|
update test_data
|
||||||
|
<set>
|
||||||
|
<if test="name != null">
|
||||||
|
name = #{name}
|
||||||
|
</if>
|
||||||
|
</set>
|
||||||
|
where `id` = #{id}
|
||||||
|
"""
|
||||||
|
return db.update(sql)
|
||||||
|
```
|
||||||
|
|
||||||
|
### foreach
|
||||||
|
```javascript
|
||||||
|
var sql = """
|
||||||
|
select * from test_data
|
||||||
|
where id in
|
||||||
|
<foreach item='item' index='index' collection='body.ids'
|
||||||
|
open="(" separator="," close=")">
|
||||||
|
#{item}
|
||||||
|
</foreach>
|
||||||
|
"""
|
||||||
|
return db.select(sql)
|
||||||
|
```
|
||||||
47
magic-script-skill/references/quick-param.md
Normal file
47
magic-script-skill/references/quick-param.md
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# 请求参数获取
|
||||||
|
|
||||||
|
## RequestParam
|
||||||
|
```
|
||||||
|
GET http://localhost:9999/xxx/xxx?name=abc&age=49
|
||||||
|
```
|
||||||
|
这样的`URL`参数`magic-api` 会自动将`name`和`age`映射为同名变量。
|
||||||
|
|
||||||
|
## 表单参数
|
||||||
|
```
|
||||||
|
POST http://localhost:9999/xxx/xxx
|
||||||
|
name=abc&age=49
|
||||||
|
```
|
||||||
|
这样的表单参数`magic-api` 也会自动将`name`和`age`映射为同名变量。
|
||||||
|
|
||||||
|
## Request Header参数获取
|
||||||
|
`magic-api` 会对所有`RequestHeader`统一封装为一个名为`header`的变量
|
||||||
|
如要获取 `token` 可以通过`header.token` 来获取
|
||||||
|
|
||||||
|
## Request Body参数获取
|
||||||
|
对于`RequestBody` `magic-api`会将整个请求体映射为`body`变量,如:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "magic-api",
|
||||||
|
"version": "9.9.9"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
如要获取`name`属性 则可通过 `body.name` 来获取
|
||||||
|
|
||||||
|
如果提交的body为数组或者List, `body`为数组。
|
||||||
|
|
||||||
|
## Path参数获取
|
||||||
|
主要是针对`URL`定义为`http://localhost:9999/user/{id}` 的类似接口
|
||||||
|
如要获取path路径上的id可通过`path.id` 或 `id`来获取。
|
||||||
|
|
||||||
|
对于请求时使用了`http://localhost:9999/user/1?id=2`的请求, `id`变量的值将是`RequestParam`中的值,此时可以通过`path.id` 来避免冲突。
|
||||||
|
|
||||||
|
## Cookie参数获取
|
||||||
|
`magic-api` 会对所有`Cookie`统一封装为一个名为`cookie`的对象。
|
||||||
|
如要获取 `JSESSIONID` 可以通过`cookie.JSESSIONID` 来获取。
|
||||||
|
|
||||||
|
## Session参数获取
|
||||||
|
`magic-api` 会将`HttpSession`封装为一个名为`session`的变量
|
||||||
|
要获取`session`中的值,可以通过`session.xxx`来获取
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
如果脚本自定义变量和参数变量冲突,自定义变量优先。
|
||||||
66
magic-script-skill/references/quick-start.md
Normal file
66
magic-script-skill/references/quick-start.md
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# 快速入门
|
||||||
|
|
||||||
|
## 初始化工程
|
||||||
|
创建一个空的`Spring Boot`工程, 以`mysql`作为默认数据库进行演示。
|
||||||
|
|
||||||
|
## 添加依赖
|
||||||
|
引入`Spring Boot Starter`父工程:
|
||||||
|
```xml
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>spring-boot-latest-version</version>
|
||||||
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
```
|
||||||
|
|
||||||
|
引入`magic-api-spring-boot-starter`依赖:
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.ssssssss</groupId>
|
||||||
|
<artifactId>magic-api-spring-boot-starter</artifactId>
|
||||||
|
<version>magic-api-lastest-version</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 配置
|
||||||
|
`application.yml`
|
||||||
|
```yaml
|
||||||
|
server:
|
||||||
|
port: 9999
|
||||||
|
magic-api:
|
||||||
|
web: /magic/web
|
||||||
|
resource:
|
||||||
|
location: D:/data/magic-api
|
||||||
|
|
||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
driver-class-name: com.mysql.jdbc.Driver
|
||||||
|
url: jdbc:mysql://localhost:3306/magic-api-test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
|
||||||
|
username: root
|
||||||
|
password: test
|
||||||
|
```
|
||||||
|
|
||||||
|
## 访问api管理界面
|
||||||
|
启动项目之后,访问`http://localhost:9999/magic/web` 即可看到Web页面
|
||||||
|
|
||||||
|
## 三分钟写出查询接口
|
||||||
|
**1. 创建分组**
|
||||||
|
点击创建分组按钮后,输入分组信息,点击创建。
|
||||||
|
|
||||||
|
**2. 新建接口**
|
||||||
|
右键分组,点击新建接口。在编辑器输入内容后,填写接口名称和及其路径。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var sql = """
|
||||||
|
select * from test_data
|
||||||
|
"""
|
||||||
|
return db.select(sql)
|
||||||
|
```
|
||||||
|
|
||||||
|
`ctrl+s`保存后,即可访问接口。
|
||||||
|
|
||||||
|
**3.访问接口**
|
||||||
|
```
|
||||||
|
> curl http://localhost:9999/test/test
|
||||||
|
```
|
||||||
64
magic-script-skill/references/request-module.md
Normal file
64
magic-script-skill/references/request-module.md
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# Request模块
|
||||||
|
|
||||||
|
## 引用模块
|
||||||
|
```javascript
|
||||||
|
import request;
|
||||||
|
```
|
||||||
|
|
||||||
|
## getFile
|
||||||
|
- 入参:`name`:`string`
|
||||||
|
- 返回值:`MultipartFile`
|
||||||
|
- 函数说明:获取上传的文件
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import request;
|
||||||
|
request.getFile('image');
|
||||||
|
```
|
||||||
|
|
||||||
|
## getFiles
|
||||||
|
- 入参:`name`:`String`
|
||||||
|
- 返回值:`List<MultipartFile>`
|
||||||
|
- 函数说明:获取上传的文件集合
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import request;
|
||||||
|
request.getFiles('image');
|
||||||
|
```
|
||||||
|
|
||||||
|
## getValues
|
||||||
|
- 入参:`name`:`String`
|
||||||
|
- 返回值:`List<String>`
|
||||||
|
- 函数说明:获取提交的数组参数
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import request;
|
||||||
|
return request.getValues('name');
|
||||||
|
```
|
||||||
|
|
||||||
|
## getHeaders
|
||||||
|
- 入参:`name`:`String`
|
||||||
|
- 返回值:`List<String>`
|
||||||
|
- 函数说明:获取请求的header数组
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import request;
|
||||||
|
return request.getHeaders('xxx');
|
||||||
|
```
|
||||||
|
|
||||||
|
## get
|
||||||
|
- 返回值:`MagicHttpServletRequest`
|
||||||
|
- 函数说明:获取`Request`对象
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import request;
|
||||||
|
request.get();
|
||||||
|
```
|
||||||
|
|
||||||
|
## getClientIP
|
||||||
|
- 返回值:`String`
|
||||||
|
- 函数说明:获取客户端`IP`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import request;
|
||||||
|
return request.getClientIP();
|
||||||
|
```
|
||||||
141
magic-script-skill/references/response-module.md
Normal file
141
magic-script-skill/references/response-module.md
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
# Response模块
|
||||||
|
|
||||||
|
## 引用模块
|
||||||
|
```javascript
|
||||||
|
import response;
|
||||||
|
```
|
||||||
|
|
||||||
|
## page
|
||||||
|
- 入参:`total`:`long`
|
||||||
|
- 入参:`values`:`list`
|
||||||
|
- 返回值:`Object`
|
||||||
|
- 函数说明:构建分页结果
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import response;
|
||||||
|
//返回: 共计10条,第一页的5条数据
|
||||||
|
return response.page(10,[1,2,3,4,5]);
|
||||||
|
```
|
||||||
|
|
||||||
|
## json
|
||||||
|
- 入参:`value`:`Object`
|
||||||
|
- 返回值:`ResponseEntity`
|
||||||
|
- 函数说明:构建Json结果
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import response;
|
||||||
|
//直接返回该json,不会被包装处理
|
||||||
|
return response.json({
|
||||||
|
success : true,
|
||||||
|
message : '执行成功'
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## text
|
||||||
|
- 入参:`value`:`String` 文本内容
|
||||||
|
- 返回值:`ResponseEntity`
|
||||||
|
- 函数说明:输出文本
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import response;
|
||||||
|
//直接返回该text,不会被包装处理
|
||||||
|
return response.text('ok');
|
||||||
|
```
|
||||||
|
|
||||||
|
## redirect
|
||||||
|
- 入参:`url`:`String` 目标网址
|
||||||
|
- 返回值:`ResponseEntity`
|
||||||
|
- 函数说明:重定向
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import response;
|
||||||
|
//重定向到该地址,内部利用HttpServletResponse的sendRedirect方法
|
||||||
|
return response.redirect('/xxx/xx');
|
||||||
|
```
|
||||||
|
|
||||||
|
## download
|
||||||
|
- 入参:`value`:`Object`
|
||||||
|
- 入参:`filename`:`文件名`
|
||||||
|
- 返回值:`ResponseEntity`
|
||||||
|
- 函数说明:下载文件
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import response;
|
||||||
|
return response.download('文件内容','test.txt');
|
||||||
|
```
|
||||||
|
|
||||||
|
## image
|
||||||
|
- 入参:`value`:`Object`
|
||||||
|
- 入参:`mine`:`String`
|
||||||
|
- 返回值:`ResponseEntity`
|
||||||
|
- 函数说明:主要用于输出图片
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import response;
|
||||||
|
// 输出图片
|
||||||
|
return response.image(bytes,'image/png');
|
||||||
|
```
|
||||||
|
|
||||||
|
## addHeader
|
||||||
|
- 入参:`key`:`string`
|
||||||
|
- 入参:`value`:`String`
|
||||||
|
- 返回值:无返回值
|
||||||
|
- 函数说明:添加Response Header
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import response;
|
||||||
|
response.addHeader('AccessToken','123');
|
||||||
|
```
|
||||||
|
|
||||||
|
## setHeader
|
||||||
|
- 入参:`key`:`string`
|
||||||
|
- 入参:`value`:`String`
|
||||||
|
- 返回值:无返回值
|
||||||
|
- 函数说明:设置Response Header
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import response;
|
||||||
|
response.setHeader('AccessToken','123');
|
||||||
|
```
|
||||||
|
|
||||||
|
## addCookie
|
||||||
|
- 入参:`key`:`string`
|
||||||
|
- 入参:`value`:`String`
|
||||||
|
- 入参:`options`:`Map` cookie参数,可选
|
||||||
|
- 返回值:无返回值
|
||||||
|
- 函数说明:添加Cookie
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import response;
|
||||||
|
response.addCookie('cookieKey','cookieValue');
|
||||||
|
response.addCookie('cookieKey','cookieValue',{
|
||||||
|
path : '/',
|
||||||
|
httpOnly : true,
|
||||||
|
domain : 'ssssssss.org',
|
||||||
|
maxAge : 3600
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## addCookies
|
||||||
|
- 入参:`cookies`:`Map` cookie Map,必填
|
||||||
|
- 入参:`options`:`Map` cookie参数,可选
|
||||||
|
- 返回值:无返回值
|
||||||
|
- 函数说明:批量添加Cookie
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import response;
|
||||||
|
response.addCookies({
|
||||||
|
cookieKey1 : 'cookieValue1',
|
||||||
|
cookieKey2 : 'cookieValue2',
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## getOutputStream
|
||||||
|
- 返回值:`OutputStream`
|
||||||
|
- 函数说明:获取`ServletOutputStream`
|
||||||
|
|
||||||
|
注意:在调用`getOutputStream`后 返回值应为`response.end()` 告诉框架无需处理返回值。
|
||||||
|
|
||||||
|
## end
|
||||||
|
- 返回值:无返回值
|
||||||
|
- 函数说明:取消返回默认的json结构,通过其他方式的输出结果(如:调用outputstream输出)
|
||||||
163
magic-script-skill/references/script-syntax.md
Normal file
163
magic-script-skill/references/script-syntax.md
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
# 脚本语法详解
|
||||||
|
|
||||||
|
## for循环
|
||||||
|
|
||||||
|
### 循环集合
|
||||||
|
```javascript
|
||||||
|
var list = [1,2,3];
|
||||||
|
for(index,item in list){ //如果不需要index,也可以写成for(item in list)
|
||||||
|
println(index + ":" + item);
|
||||||
|
}
|
||||||
|
// 结果:0:1, 1:2, 2:3
|
||||||
|
```
|
||||||
|
|
||||||
|
### 循环指定次数
|
||||||
|
```javascript
|
||||||
|
var sum = 0;
|
||||||
|
for(value in range(0,100)){ //包括0包括100
|
||||||
|
sum = sum + value; //不支持+= -= *= /= ++ -- 这种运算
|
||||||
|
}
|
||||||
|
return sum; // 5050
|
||||||
|
```
|
||||||
|
|
||||||
|
## while循环
|
||||||
|
```javascript
|
||||||
|
var count = 100;
|
||||||
|
var sum = 0;
|
||||||
|
while(count){
|
||||||
|
sum = sum + count;
|
||||||
|
count = count - 1;
|
||||||
|
}
|
||||||
|
return sum; // 5050
|
||||||
|
```
|
||||||
|
|
||||||
|
## 循环map
|
||||||
|
```javascript
|
||||||
|
var map = {
|
||||||
|
key1 : 123,
|
||||||
|
key2 : 456
|
||||||
|
};
|
||||||
|
for(key,value in map){ //如果不需要key,也可以写成for(value in map)
|
||||||
|
println(key + ":" + value);
|
||||||
|
}
|
||||||
|
// 结果:key1:123, key2:456
|
||||||
|
```
|
||||||
|
|
||||||
|
## Import导入
|
||||||
|
|
||||||
|
### 导入Java类
|
||||||
|
```javascript
|
||||||
|
import 'java.lang.System' as System;
|
||||||
|
import 'javax.sql.DataSource' as ds;
|
||||||
|
import 'org.apache.commons.lang3.StringUtils' as string;
|
||||||
|
import 'java.text.*' // 此写法跟Java一致
|
||||||
|
|
||||||
|
System.out.println('调用System打印');
|
||||||
|
System.out.println(ds);
|
||||||
|
System.out.println(string.isBlank(''));
|
||||||
|
System.out.println(new SimpleDateFormat('yyyy-MM-dd').format(new Date()));
|
||||||
|
```
|
||||||
|
|
||||||
|
### 导入已定义的模块
|
||||||
|
```javascript
|
||||||
|
import log; //导入log模块,并定义一个与模块名相同的变量名
|
||||||
|
//import log as logger; //导入log模块,并赋值给变量 logger
|
||||||
|
log.info('Hello {}','Magic API!')
|
||||||
|
```
|
||||||
|
|
||||||
|
## new创建对象
|
||||||
|
```javascript
|
||||||
|
import 'java.util.Date' as Date;//创建之前先导包,不支持.*的操作
|
||||||
|
return new Date();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 异步调用
|
||||||
|
|
||||||
|
### 异步调用方法
|
||||||
|
```javascript
|
||||||
|
var val = async db.select('.....'); // 异步调用,返回Future类型
|
||||||
|
return val.get(); //调用Future的get方法
|
||||||
|
```
|
||||||
|
|
||||||
|
### 异步调用lambda
|
||||||
|
```javascript
|
||||||
|
var list = [];
|
||||||
|
for(index in range(1,10)){
|
||||||
|
list.add(async (index)=>db.selectInt('select #{index}'));
|
||||||
|
}
|
||||||
|
return list.map(item=>item.get()); // 循环获取结果
|
||||||
|
```
|
||||||
|
|
||||||
|
## exit
|
||||||
|
语法格式为 `exit expr[,expr][,expr]....`
|
||||||
|
|
||||||
|
在`magic-api`中只取前三个值,分别对应`code`、`message`、`data`
|
||||||
|
|
||||||
|
如:`exit 400,'参数填写有误'`
|
||||||
|
|
||||||
|
## assert
|
||||||
|
语法格式为 `assert expr : expr[,expr][,expr]....`
|
||||||
|
|
||||||
|
如:`assert a == 1 : 400, 'a的值应为1'` 相当于
|
||||||
|
```javascript
|
||||||
|
if(a != 1){
|
||||||
|
exit 400, 'a的值应为1'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 类型转换
|
||||||
|
通过`::`进行类型转换,如`xxx::int`、`xxx::double`等,当前支持转换类型有`int`、`double`、`long`、`byte`、`short`、`float`、`date`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var a = "1";
|
||||||
|
return {
|
||||||
|
v1: a::int,
|
||||||
|
v2: a::int(0), //转换失败时,值为0
|
||||||
|
v3: "2020-01-01"::date('yyyy-MM-dd') //转为Date
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`::sql`支持将数据转换为对应的sql类型,比如:
|
||||||
|
```javascript
|
||||||
|
img::sql('blob')
|
||||||
|
```
|
||||||
|
可传入的参数请参考`java.sql.Types`中定义的常量,不区分大小写。
|
||||||
|
|
||||||
|
## 嵌入其它脚本语言
|
||||||
|
```javascript
|
||||||
|
var name = "hello";
|
||||||
|
var test = ```javascript
|
||||||
|
name + ' ~ world'
|
||||||
|
```;
|
||||||
|
return test();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 可选链操作符
|
||||||
|
可选链操作符(`?.`)允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var a = null;
|
||||||
|
var b = a?.name; // b = null;
|
||||||
|
var c = a?.getName(); // c = null;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 扩展运算符
|
||||||
|
扩展运算符,又叫展开语法(Spread syntax),是用于将list或map在语法层面展开
|
||||||
|
|
||||||
|
### lambda 调用
|
||||||
|
```javascript
|
||||||
|
var sum = (a,b,c) => a + b + c;
|
||||||
|
System.out.println(sum(...[1,2,3])) // 结果:6
|
||||||
|
```
|
||||||
|
|
||||||
|
### list 展开
|
||||||
|
```javascript
|
||||||
|
var arr = [3,4,5];
|
||||||
|
System.out.println([1,2,...arr,6,7]) // 结果:[1, 2, 3, 4, 5, 6, 7]
|
||||||
|
```
|
||||||
|
|
||||||
|
### map 展开
|
||||||
|
```javascript
|
||||||
|
var map = {key2:2}
|
||||||
|
System.out.println({key1:1,...map,key3:3}) // 结果:{key1=1, key2=2, key3=3}
|
||||||
|
```
|
||||||
104
magic-script-skill/references/single-table.md
Normal file
104
magic-script-skill/references/single-table.md
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
# 单表操作
|
||||||
|
|
||||||
|
操作入口:`db.table('table_name')`
|
||||||
|
|
||||||
|
## logic
|
||||||
|
- 作用:设置本查询是带有逻辑删除的,在执行`delete`方法时,会转换为`update`语句,在执行`select`相关方法时,会拼接`logic_field <> logic_value`
|
||||||
|
|
||||||
|
## withBlank
|
||||||
|
- 作用:设置后续插入或修改时,不过滤空值。
|
||||||
|
|
||||||
|
## column
|
||||||
|
- 入参:`column`: `String` 列名
|
||||||
|
- 作用:设置要查询列,`select`语句中有效
|
||||||
|
|
||||||
|
## column
|
||||||
|
- 入参:`column`: `String` 列名
|
||||||
|
- 入参:`value` : `Object` 值
|
||||||
|
- 作用:设置要操作的列的值,非`select`语句中有效
|
||||||
|
|
||||||
|
## primary
|
||||||
|
- 入参:`primary`: `String` 主键
|
||||||
|
- 入参:`defaultValue`: `Object` 插入时使用的默认值,可省略
|
||||||
|
- 作用:设置主键列,在`update`中语句有效,或`save`方法判断标准
|
||||||
|
|
||||||
|
## insert
|
||||||
|
- 入参: `data` : `Map` `insert`的列和值,可省略(通过`column`设置)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// insert into sys_user(user_name,role) values('李富贵','admin')
|
||||||
|
return db.table('sys_user').insert({ user_name : '李富贵', role : 'admin'})
|
||||||
|
```
|
||||||
|
|
||||||
|
## batchInsert
|
||||||
|
- 入参: `collection` : `Collection` `insert`的列和值的集合
|
||||||
|
- 入参: `batchSize` : `int` batchSize
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return db.table('sys_user').batchInsert([
|
||||||
|
{ user_name : '李富贵', role : 'admin'},
|
||||||
|
{ user_name : '王二狗', role : 'admin'},
|
||||||
|
{ user_name : '管理员', role : 'super-admin'},
|
||||||
|
])
|
||||||
|
```
|
||||||
|
|
||||||
|
## update
|
||||||
|
- 入参: `data` : `Map` `insert`的列和值,可省略(通过`column`设置)
|
||||||
|
- 入参:`isUpdateBlank`: `boolean` 是否更新空值字段(可省略,默认为`false`)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// update sys_user set user_name = '王二狗' where id = 1
|
||||||
|
return db.table('sys_user').primary('id').update({ id: 1, user_name : '王二狗'})
|
||||||
|
```
|
||||||
|
|
||||||
|
## save
|
||||||
|
- 入参: `data` : `Map` `insert`或`update`的列和值,可省略(通过`column`设置)
|
||||||
|
- 入参:`beforeQuery` : `boolean` 是否根据id查询有没有数据,可省略(默认`false`)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// insert into sys_user(id,user_name) values('xxx','王二狗');
|
||||||
|
return db.table('sys_user').primary('id', uuid()).save({user_name: '王二狗'});
|
||||||
|
// insert into sys_user(user_name) values('王二狗');
|
||||||
|
return db.table('sys_user').primary('id').save({user_name: '王二狗'});
|
||||||
|
// update sys_user set user_name = '王二狗' where id = 1
|
||||||
|
return db.table('sys_user').primary('id').save({id: 1,user_name: '王二狗'});
|
||||||
|
```
|
||||||
|
|
||||||
|
## select
|
||||||
|
查询list(与db.select 作用相同)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// select * from sys_user
|
||||||
|
return db.table('sys_user').select()
|
||||||
|
```
|
||||||
|
|
||||||
|
## page
|
||||||
|
分页查询(与db.page 作用相同)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// select * from sys_user
|
||||||
|
return db.table('sys_user').page()
|
||||||
|
```
|
||||||
|
|
||||||
|
## where
|
||||||
|
设置查询条件
|
||||||
|
|
||||||
|
- eq --> `==`
|
||||||
|
- ne --> `<>`
|
||||||
|
- lt --> `<`
|
||||||
|
- gt --> `>`
|
||||||
|
- lte --> `<=`
|
||||||
|
- gte --> `>=`
|
||||||
|
- in --> `in`
|
||||||
|
- notIn --> `not in`
|
||||||
|
- like --> `like`
|
||||||
|
- notLike --> `not like`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// select * from sys_user where user_name like '%李富贵%' and role = 'admin'
|
||||||
|
return db.table('sys_user')
|
||||||
|
.where()
|
||||||
|
.like('user_name','%李富贵%')
|
||||||
|
.eq('role','admin')
|
||||||
|
.select()
|
||||||
|
```
|
||||||
125
magic-script-skill/references/sql-param.md
Normal file
125
magic-script-skill/references/sql-param.md
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
# SQL参数
|
||||||
|
|
||||||
|
## #{} 注入参数
|
||||||
|
作用和`mybatis`一致,都是将`#{}`区域替换为占位符`?`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var id = 123;
|
||||||
|
return db.select("""
|
||||||
|
select * from sys_user where id = #{id}
|
||||||
|
""");
|
||||||
|
// 运行时生成的SQL为:select * from sys_user where id = ?
|
||||||
|
```
|
||||||
|
|
||||||
|
此方法可以避免`sql`注入。
|
||||||
|
|
||||||
|
## ${} 拼接参数
|
||||||
|
作用和`mybatis`一致,都是将`${}`区域替换为对应的字符串
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var id = 123;
|
||||||
|
return db.select("""
|
||||||
|
select * from sys_user where id = ${id}
|
||||||
|
""");
|
||||||
|
// 运行时生成的SQL为:select * from sys_user where id = 123
|
||||||
|
```
|
||||||
|
|
||||||
|
## 动态SQL参数
|
||||||
|
通过`?{condition,expression}`来实现动态拼接`SQL`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return db.select("select * from sys_user ?{id,where id = #{id}}");
|
||||||
|
// 当id有值时,生成SQL:select * from sys_user where id = ?
|
||||||
|
// 当id无值时,生成SQL:select * from sys_user
|
||||||
|
|
||||||
|
return db.select("select * from sys_user ?{id!=null&&id.length() > 3,where id = #{id}}");
|
||||||
|
```
|
||||||
|
|
||||||
|
## 循环拼接参数
|
||||||
|
两种办法:
|
||||||
|
|
||||||
|
### in语法自动展开
|
||||||
|
```javascript
|
||||||
|
var ids = [1,2,3,4,5,6];
|
||||||
|
//会自动变成select * from sys_user where id in(?,?,?,?,?,?)
|
||||||
|
return db.select('select * from sys_user where id in(#{ids})');
|
||||||
|
```
|
||||||
|
|
||||||
|
### 循环拼接SQL
|
||||||
|
```javascript
|
||||||
|
var list = [1,2,3,4,5];
|
||||||
|
var sql = "select * from sys_user where ";
|
||||||
|
for(index,item in list){
|
||||||
|
sql = sql + 'id = #{list['+index+']}';
|
||||||
|
if(index + 1 < list.size()){
|
||||||
|
sql = sql + ' or ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return db.select(sql);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mybatis语法支持
|
||||||
|
|
||||||
|
### 支持的关键字
|
||||||
|
- `<if>`
|
||||||
|
- `<elseif>`
|
||||||
|
- `<else>`
|
||||||
|
- `<where>`
|
||||||
|
- `<foreach>`
|
||||||
|
- `<trim>`
|
||||||
|
- `<set>`
|
||||||
|
|
||||||
|
### if
|
||||||
|
```javascript
|
||||||
|
var sql = """
|
||||||
|
select * from test_data
|
||||||
|
where 1 = 1
|
||||||
|
<if test="id != null">
|
||||||
|
and id = #{id}
|
||||||
|
</if>
|
||||||
|
"""
|
||||||
|
return db.select(sql)
|
||||||
|
```
|
||||||
|
|
||||||
|
### where
|
||||||
|
```javascript
|
||||||
|
var sql = """
|
||||||
|
select * from test_data
|
||||||
|
<where>
|
||||||
|
<if test="id != null">
|
||||||
|
and id = #{id}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
"""
|
||||||
|
return db.select(sql)
|
||||||
|
```
|
||||||
|
|
||||||
|
### set、trim
|
||||||
|
```javascript
|
||||||
|
var sql = """
|
||||||
|
update test_data
|
||||||
|
<set>
|
||||||
|
<if test="name != null">
|
||||||
|
name = #{name}
|
||||||
|
</if>
|
||||||
|
<if test="content != null">
|
||||||
|
content = #{content}
|
||||||
|
</if>
|
||||||
|
</set>
|
||||||
|
where `id` = #{id}
|
||||||
|
"""
|
||||||
|
return db.update(sql)
|
||||||
|
```
|
||||||
|
|
||||||
|
### foreach
|
||||||
|
```javascript
|
||||||
|
var sql = """
|
||||||
|
select * from test_data
|
||||||
|
where id in
|
||||||
|
<foreach item='item' index='index' collection='body.ids'
|
||||||
|
open="(" separator="," close=")">
|
||||||
|
#{item}
|
||||||
|
</foreach>
|
||||||
|
"""
|
||||||
|
return db.select(sql)
|
||||||
|
```
|
||||||
26
magic-script-skill/references/string-functions.md
Normal file
26
magic-script-skill/references/string-functions.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# 字符串函数
|
||||||
|
|
||||||
|
## uuid
|
||||||
|
- 返回值: `String` `32`位无`-`的`UUID`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return uuid(); // 等同于 UUID.randomUUID().toString().replace("-", "");
|
||||||
|
```
|
||||||
|
|
||||||
|
## is_blank
|
||||||
|
- 入参:`target`:`String` 判断的目标
|
||||||
|
- 返回值:`boolean`
|
||||||
|
- 函数说明:判断字符串是否为空
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return is_blank(''); // true 等同于 StringUtils.isBlank 一致
|
||||||
|
```
|
||||||
|
|
||||||
|
## not_blank
|
||||||
|
- 入参:`target`:`String` 判断的目标
|
||||||
|
- 返回值:`boolean`
|
||||||
|
- 函数说明:判断字符串是否不为空
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return not_blank(''); // false 等同于 !is_blank('')
|
||||||
|
```
|
||||||
22
magic-script-skill/references/validate.md
Normal file
22
magic-script-skill/references/validate.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# 参数校验
|
||||||
|
|
||||||
|
## 自动验证
|
||||||
|
在magic-api的Web界面中,可配置:
|
||||||
|
- 必填验证
|
||||||
|
- 表达式验证
|
||||||
|
- 正则验证
|
||||||
|
|
||||||
|
## 手动验证
|
||||||
|
对于表达式和正则无法实现的可以通过脚本来实现。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var count = db.selectInt("""
|
||||||
|
select count(*) from sys_user where phone = #{phone}
|
||||||
|
""")
|
||||||
|
// count 值应该为0,如果不为0则验证不予通过。
|
||||||
|
assert count == 0 : 400, '手机号已存在';
|
||||||
|
// 上述写法可以转换为
|
||||||
|
if(count != 0){
|
||||||
|
exit 400, '手机号已存在'
|
||||||
|
}
|
||||||
|
```
|
||||||
Loading…
Reference in New Issue
Block a user