# 低代码文档

通过配置json文件的形式去创建带crud的控制器代码

# 项目结构

├── extend
│   ├── builder
│   │   └── index.js
│   ├── helper
│   │   └── index.js
│   └── validator
│       ├── index.js
│       └── rule_parser.js
├── generator
│   ├── base
│   │   └── index.js
│   ├── controller
│   │   └── index.js
│   └── service
│       └── index.js
├── index.js
├── module
│   ├── common
│   │   ├── field.js
│   │   ├── group.js
│   │   ├── having.js
│   │   ├── join.js
│   │   ├── order.js
│   │   ├── orm.js
│   │   ├── pagination.js
│   │   ├── relation.js
│   │   ├── validator.js
│   │   └── where.js
│   └── index.js
├── package.json
└── README.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 如何使用

创建一个存放json配置文件的目录, 并且编写所需要的json配置文件, 然后将目录配置到 生成器 里面, 使用 node 命令运行生成器文件

# 快速创建

  1. 安装
npm i @kbd151/code-generator
1
  1. 创建空目录与执行文件
#文件夹说明
#gen/prod文件夹会提交到git仓库,里面的json会自动被框架载入并注册到路由里面

# 生成配置文件夹
mkdir -vp gen/local/controller
mkdir -vp gen/local/service
# 生成配置文件
touch gen/local/controller/xxx.json
touch gen/local/service/xxx.json
# 生成入口文件
touch gen.js
1
2
3
4
5
6
7
8
9
10
11
  1. 入口文件
const gen = require('@kbd151/code-generator')

function optionFile(file) {
  console.log(`使用文件 ${file}`);
  return true
}

function help() {
  console.log('选项:');
  console.log('  -cf    指定控制器配置文件');
  console.log('  -sf    指定服务配置文件');
  console.log('  help   显示帮助');
}

const args = process.argv.slice(2);

let cf,sf
for (let i = 0; i < args.length; i++) {
  if (args[i] === '-cf') {
    cf = args[i + 1];
  }else if(args[i] === '-sf'){
    sf = args[i + 1];
  }
}

if (args.includes('help')) {
  help();
} else if (!cf && !sf){
  console.log('无效命令。你必须用 -cf 指定控制器配置文件 或 -sf 指定服务配置文件。');
}

cf && optionFile(cf) && gen.controllerGen.generate({
  filePath: cf,
  appPath: 'server/app/controller'
})


sf && optionFile(sf) && gen.serviceGen.generate({
  filePath: sf,
  appPath: 'server/app/service'
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
  1. 控制器json文件
{
  "name": "推品接口",
  "moduleName": "promotion",
  "extend": {"name": "WwwController", "path": "base/www_controller"},
  "outputPath": "promotion/goods.js",
  "routes": [
    {
      "moduleName": "goodsPromotionDetail",
      "method": "GET",
      "version": "v1",
      "comment": "查询推品信息",
      "permission": false,
      "type": "query",
      "service": {
        "moduleName": "promotionService.goodsService.goodsPromotionDetail",
        "hasReturn": true
      }
    }
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  1. 执行入口文件
node gen.js -cf gen/local/controller/goods.json

#输出
#使用文件 gen/local/controller/goods.json
#文件生成成功,路径:server/app/controller/promotion/goods.js
1
2
3
4
5
  1. 执行得到下面的js

const _ = require('lodash')
const moment = require('moment')
const gen = require('@kbd151/code-generator')
const permission = true
const moduleName = 'promotion'
const {WwwController} = require('../base/www_controller')


/**
 * 查询推品信息
 */
module.exports.goodsPromotionDetail = class extends WwwController {
  permission = false
  url = "/v1/" + moduleName + "/goods_promotion_detail"
  async get({ query }) {
    return await this.promotionService.goodsService.goodsPromotionDetail({ body: query })
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  1. 服务配置文件
{
  "name": "推品服务",
  "moduleName": "goodsService",
  "extend": {"name": "BaseService", "path": "base/base_service"},
  "outputPath": "promotion/goods.js",
  "routes": [
    {
      "moduleName": "goodsPromotionDetail",
      "comment": "推品详情",
      "type": "query",
      "operateLists": {
        "comment": "查询详情",
        "model": "xpinModel.XpinGoodsPromotion",
        "pagination": {
          "paginate": true
        },
        "method": "findAndCountAll",
        "params": {
          "attributes": ["title", "price", "shop_id"],
          "where": [
          ],
          "relation": [
            {
              "method": "relateMany",
              "model": "xpinModel.XpinShop",
              "localField": "id",
              "fromField": "shop_id",
              "as": "shop",
              "attributes": ["shop_name", "id"],
              "where": [
                {"id": {"op": ">","value": 0}}
              ]
            }
          ]
        }
      }
    }
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  1. 执行入口文件
node gen.js -sf gen/local/service/goods.json

#输出
#使用文件 gen/local/service/goods.json
#文件生成成功,路径:server/app/service/promotion/goods.js
1
2
3
4
5
  1. 发起请求后得到响应
{
    "success": true,
    "data": {
        "count": 7200,
        "rows": [
            {
                "title": "圣诞节 中闽飘香 拍1发3 冻干柠檬片",
                "price": 3480,
                "shop_id": 19338,
                "shop": [
                    {
                        "shop_name": "中闽飘香专卖店",
                        "id": 19338
                    }
                ]
            },
            ...
        ]
    },
    "code": 0
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  1. 说明

如果提示service不存在,自行去基础类实例化一下

# 如何配置

# 基本数据结构:

字段 类型 必填项 说明
name string 关于这个json文件的说明
moduleName string 模块名
extend array 需要继承的类信息
extend.name string 需要继承的类的名字
extend.path string 需要继承的类引入的路径
outputPath string 文件输出地址,仅生成代码填写
routes array 控制器/服务路由配置

# 控制器内routes结构

字段 类型 必填项 说明
moduleName string 驼峰形式的模块名, 也就是控制器类名
method string get/post 方法
version string 版本, 默认填写 v1
comment string 当前模块的注释
permission bool 是否鉴权, 默认: 是
type string 类型: query=>查询, update=>修改
inject array 需要注入的变量, 比如company,admin
validate object 验证器
operateLists object 操作列表, 查询/更新的具体orm操作
service object 服务类

# 服务内routes结构

字段 类型 必填项 说明
moduleName string 驼峰形式的模块名, 也就是服务名
comment string 当前模块的注释
type string 类型: query=>查询, update=>修改
inject array 需要注入的变量, 比如company,admin
operateLists object 操作列表, 查询/更新的具体orm操作

# validate结构

字段 说明 例子
required 必填字段 required
alpha 只能包含字母 alpha
alphaDash 只能包含字母、数字、破折号或下划线 alphaDash
alphaNum 只能包含字母和数字 alphaNum
between 值必须在指定范围内 between: 1, 10
date 必须是有效的日期格式 date
different 值必须与指定字段的值不同 different: username
email 必须是有效的电子邮件地址 email
float 必须是浮点数 float
integer 必须是整数 integer
number 必须是数字 number
length 值的长度必须是指定长度范围内 length: 2, 500
max 值不能大于指定数值 max: 100
min 值不能小于指定数值 min: 5
regex 值必须符合指定的正则表达式 regex: ^[A-Z]+$
string 必须是字符串 string
in 必须在列表里 in: 1, 2, 3
notIn 必须不在列表里 notIn: 1, 2, 3
url url验证 url
gt 必须大于指定的数值 gt: 10
lt 必须小于指定的数值 lt: 10
gte 必须大于等于指定的数值 gte: 20
lte 必须小于等于指定的数值 lte: 20

# service结构

字段 类型 必填项 说明
moduleName string 要调用的模块名,例如:promotionService.goodsService.goodsPromotionDetail
hasReturn bool 是否有返回值,如果有返回值,那么当前的控制器就会直接返回服务类的内容给前端

# operateLists结构

字段 类型 必填项 说明
comment string 关于这个orm操作的说明
model string 要操作的model, 需要具体到数据库名, 例如:xpinModel.XpinGoodsPromotion
method string 要操作的方法, 也就是sequelize的方法,例如:update,findOne
pagination object 分页配置
params object orm操作表的配置参数

# pagination结构

字段 类型 必填项 说明
paginate bool 是否分页
jsonContains array json搜索
timestamps array
timestamps_origin array
dates array 时间范围过虑
likes array 模糊搜索
jsonContainsNone array

# params结构

字段 类型 必填项 说明
attributes array 要查询的字段, 如果要查询的字段包含 +-*/()符号或者包含` as `, 会直接作为原生sql拼装查询
order array 排序, 二维数组, 例如: ["XpinGoodsPromotion.id","desc"]
group array 分组, 如果分组的字段包含 +-*/()符号, 会直接作为原生sql拼接
having string having查询直接传字符串,会当做原生sql解析
where array 查询条件配置
joins array 连表配置
relation array 关联查询,解决n+1问题
isBatchUpdate
bool 更新的时候使用, 默认 falsetrue: 仅判断是否更新成功false: 强制判断更新行数为1
createOrUpdateData object 创建/更新的数据

# where基本用法

条件字段不可以是 whereorWhere关键词

where 用于描述数据查询条件

[
  {"title": {"op": "like", "type": "js", "value": "$.title+'%'"}},
  {
    "shop_id": {
      "op": "in",
      "type": "sql",
      "value": "(select id from xpin_shop where dsr_level = 1)"
    }
  },
  {"id": {"op": "=", "type": "js", "value": "parseInt($.id)"}},
  {"where": ["XpinGoodsPromotion.sale_count > 0", {"price": 990}]},
  {
    "orWhere": [
      {"status": {"op": "in", "value": [1, 2, 3]}},
      {"id": {"op": ">", "value": 1000}}
    ]
  }
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

解析后的 SQL语句 为:

WHERE `XpinGoodsPromotion`.`title` LIKE 'a%' 
    AND `XpinGoodsPromotion`.`shop_id` IN ( SELECT id FROM xpin_shop WHERE dsr_level = 1 ) 
    AND `XpinGoodsPromotion`.`id` = 43 
    AND ( XpinGoodsPromotion.sale_count > 0 AND `XpinGoodsPromotion`.`price` = 990 ) 
    AND ( `XpinGoodsPromotion`.`status` IN ( 1, 2, 3 ) OR `XpinGoodsPromotion`.`id` > 1000 )
1
2
3
4
5

# where结构

# And & Or 嵌套

字段 类型 必填项 说明
where array 嵌套 and 操作, 也就是此数组里的所有内容 在拼接sql时 外层会单独套一层 括号, 并且数组里的第一层查询 全都是 and 的关系, 例如 在id = 1的sql 里, 拼接完之后是:id = 1and (xxx and xxx and xxx)
orWhere array 嵌套 or 操作, 也就是此数组里的所有内容 在拼接sql时 外层会单独套一层 括号, 并且数组里的第一层查询 全都是 or 的关系, 例如 在id = 1的sql 里, 拼接完之后是:id = 1and (xxx or xxx or xxx)

# 原始sql拼接

直接放sql到 where或者orWhere内的数组里即可

# 正常筛选

字段 类型 必填项 说明
field string 要搜索的字段
field.op string 默认是等于操作, 具体支持的类型翻阅 sequelize 文档, 这里我将 =,>,<,>=,<=,<>,!= 转换成了 sequelize支持的类型
field.type string 默认:value给的是什么类型,查询就是什么类型(value是变量时除外)当 type 是 js 时, 会作为js代码去执行当 type 是 sql 时, 会作为原生sql解析
field.value
string 当查询内容是对象的时候, value 必填, value里如果含有$.关键词时,$.会自动替换为 前端传来的变量, get请求就是query, post请求就是body
field.must string 过滤查询内容使用,js代码,前端的参数用$.标识出来

# joins结构

字段 类型 必填项 说明
model string 要操作的model, 需要具体到数据库名, 例如:xpinModel.XpinShop
localField string 要操作的表的关联字段shop_id
from string 连表时原model, 需要具体到数据库名, 例如:xpinModel.XpinGoodsPromotion
fromField string 原表的关联字段, 例如id
left bool 是否是左连接, 默认是左连接
attributes string 当前表要查询的字段
where array 查询条件配置
as string 别名 v1.0.13新增

# relation结构

字段 类型 必填项 说明
method string relateOne 或者 relateMany
model string 要操作的model, 需要具体到数据库名, 例如:xpinModel.XpinShop
localField string 要操作的表的关联字段shop_id
fromField string 原表的关联字段, 例如id
as string 查询的数据作为一个别放放到对象里
attributes string 当前表要查询的字段,不支持原始sql填写
where array 查询条件配置

# createOrUpdateData结构

字段 类型 必填项 说明
attributes string 要更新/新增的字段, 多个值用 逗号 分隔, 字段和参数名保持一致
appendData object 额外要更新/新增的字段数据
appendData.field string 要操作的字段场景:前端传的参数名和数据库字段不对应 或 需要额外操作的字段
appendData.type string 默认:value给的是什么类型,查询就是什么类型(value是变量时除外)当 type 是 js 时, 会作为js代码去执行当 type 是 sql 时, 会作为原生sql解析
appendData.value string value里如果含有$.关键词时,$.会自动替换为 前端传来的变量, get请求就是query, post请求就是body

# 补充说明

凡是涉及到原始sql操作的地方,都需要使用参数绑定去操作前端传过来的参数,代码生成的时候会自动做绑定

用法:

sql里前端参数直接用**:field**的格式就行,也就是前端的参数名加一个冒号

# 例子

# 连表查询和子查询

json配置

{
  "name": "推品接口",
  "moduleName": "goods",
  "extend": {"name": "WwwController", "path": "base/www_controller"},
  "outputPath": "compass/detail.js",
  "routes": [
    {
      "moduleName": "goodsPromotionDetail",
      "method": "GET",
      "version": "v1",
      "comment": "查询推品信息",
      "permission": false,
      "type": "query",
      "validate": {"id": ["required","number"]},
      "operateLists": {
        "comment": "查询详情",
        "model": "xpinModel.XpinGoodsPromotion",
        "method": "findOne",
        "params": {
          "attributes": ["title", "price"],
          "where": [
            {"title": {"op": "like", "type": "js", "value": "$.title+'%'"}},
            {
              "shop_id": {
                "op": "in",
                "type": "sql",
                "value": "(select id from xpin_shop where dsr_level = 1)"
              }
            },
            {"id": {"op": "=", "type": "js", "value": "parseInt($.id)"}},
            {"where": ["XpinGoodsPromotion.sale_count > 0", {"price": 990}]},
            {
              "orWhere": [
                {"status": {"op": "in", "value": [1, 2, 3]}},
                {"id": {"op": ">", "value": 1000}}
              ]
            }
          ],
          "joins": [
            {
              "model": "xpinModel.XpinShop",
              "localField": "id",
              "left": true,
              "from": "xpinModel.XpinGoodsPromotion",
              "fromField": "shop_id",
              "attributes": ["id as shop_id", "shop_name"],
              "as": "shop",
              "where": [
                {"id": {"op": ">", "value": 10}}
              ],
              "pagination": {
                "likes": {"shop_name": ["shop_name"]}
              }
            }
          ]
        }
      }
    }
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

对应的js代码


const _ = require('lodash')
const moment = require('moment')
const gen = require('@kbd151/code-generator')
const permission = true
const moduleName = 'goods'
const {WwwController} = require('../base/www_controller')


/**
 * 查询推品信息
 */
module.exports.goodsPromotionDetail = class extends WwwController {
  permission = false
  url = "/v1/" + moduleName + "/goods_promotion_detail"
  async get({ query }) {
    let [ok, error] = gen.validate(query, { id: ["required", "number"] })
    if (!ok) {
      return { success: false, code: 4000, msg: "参数验证失败", data: error }
    }

    // 查询详情
    let builder = new gen.sequelizeQueryBuilder()
    let queryObj = builder
      .select("title", "price", builder.raw("shop.id as shop_id"), "shop.shop_name")
      .where("title", "like", query.title + "%")
      .where("shop_id", "in", builder.raw("(select id from xpin_shop where dsr_level = 1)"))
      .where("id", "=", parseInt(query.id))
      .where(function (queryBuilder) {
        queryBuilder.whereRaw("XpinGoodsPromotion.sale_count > 0").where("price", 990)
      })
      .orWhere(function (queryBuilder) {
        queryBuilder.where("status", "in", [1, 2, 3]).where("id", ">", 1000)
      })
      .leftJoin({
        fromModel: this.xpinModel.XpinGoodsPromotion,
        fromField: "shop_id",
        toModel: this.xpinModel.XpinShop,
        toField: "id",
        as: "shop",
        where: (function (application) {
          let builder = new gen.sequelizeQueryBuilder()
          let queryObj = builder.where("id", ">", 10).build()
          application.helper.pagination({
            params: query,
            origin_data: queryObj,
            likes: { shop_name: ["shop_name"] }
          })
          return queryObj.where
        })(this.application)
      })
      .bind(query)
      .build()

    let result = await this.xpinModel.XpinGoodsPromotion.findOne(queryObj)

    return { success: true, data: result }
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

对应的sql代码

SELECT `XpinGoodsPromotion`.`title`,
 `XpinGoodsPromotion`.
 `price`,
 shop.id as shop_id,
 `shop`.`shop_name`
FROM `kbd_xuanpin`.`xpin_goods_promotion` AS `XpinGoodsPromotion`
 LEFT OUTER JOIN `kbd_xuanpin`.`xpin_shop` AS `shop`
  ON `XpinGoodsPromotion`.`shop_id` = `shop`.`id`
   AND (`shop`.`id` > 10)
   AND `shop`.`shop_name` LIKE '%444555555555555555555%'
WHERE (`XpinGoodsPromotion`.`title` LIKE 'a%'
 AND `XpinGoodsPromotion`.`shop_id` IN (select id from xpin_shop where dsr_level = 1)
 AND `XpinGoodsPromotion`.`id` = 43
 AND (XpinGoodsPromotion.sale_count > 0 AND `XpinGoodsPromotion`.`price` = 990)
 AND (`XpinGoodsPromotion`.`status` IN (1, 2, 3) OR `XpinGoodsPromotion`.`id` > 1000));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 批量写操作

json配置

{
  "name": "店铺接口",
  "moduleName": "goods",
  "extend": {"name": "WwwController", "path": "base/www_controller"},
  "outputPath": "goods/update.js",
  "routes": [
    {
      "moduleName": "updateShopInfo",
      "method": "POST",
      "version": "v1",
      "comment": "更新店铺信息",
      "type": "update",
      "permission": false,
      "validate": {
        "id": "required",
        "brand_name": "required|length:2,10",
        "city_name": "required|length:2,10",
        "author_id": "required|integer",
        "gid": "required|integer"
      },
      "operateLists": [
        {
          "model": "xpinModel.XpinShop",
          "method": "update",
          "comment": "更新店铺卖家名称",
          "params": {
            "isBatchUpdate": false,
            "where": [{"id": {"op": "=", "value": "$.id"}}],
            "createOrUpdateData": {
              "attributes": [],
              "appendData": [
                {
                  "field": "nick_name",
                  "type": "sql",
                  "value": "1+1"
                }
              ]
            }
          }
        },
        {
          "model": "xpinModel.XpinShop",
          "method": "update",
          "comment": "更新店铺品牌名称",
          "params": {
            "isBatchUpdate": false,
            "where": [{"id": {"op": "=", "value": "$.id"}}],
            "createOrUpdateData": {
              "attributes": ["brand_name"],
              "appendData": [
                {
                  "field": "city",
                  "value": "$.city_name"
                }
              ]
            }
          }
        },
        {
          "model": "xpinModel.XpinShopcaseRecord",
          "method": "create",
          "comment": "新增挂车记录",
          "params": {
            "createOrUpdateData": {
              "attributes": ["author_id"],
              "appendData": [
                {
                  "field": "goods_id",
                  "value": "$.gid"
                }
              ]
            }
          }
        }
      ]
    }
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

js代码


const _ = require('lodash')
const moment = require('moment')
const gen = require('@kbd151/code-generator')
const permission = true
const moduleName = 'goods'
const {WwwController} = require('../base/www_controller')


/**
 * 更新店铺信息
 */
module.exports.updateShopInfo = class Controller extends WwwController {
  permission = false
  url = "/v1/" + moduleName + "/update_shop_info"
  async post({ request: { body } }) {
    let [ok, error] = gen.validate(body, {
      id: "required",
      brand_name: "required|length:2,10",
      city_name: "required|length:2,10",
      author_id: "required|integer",
      gid: "required|integer"
    })
    if (!ok) {
      return { success: false, code: 4000, msg: "参数验证失败", data: error }
    }

    let transactionA = this.xpinModel.transaction()
    try {
      // 更新店铺卖家名称
      let builder = new gen.sequelizeQueryBuilder()
      let queryObjA = builder.bindTransaction(transactionA).build()
      let [updateRowsA] = await this.xpinModel.XpinShop.update(
        { nick_name: builder.raw("1+1") },
        queryObjA
      )
      if (updateRowsA !== 1) {
        throw new Error("更新失败")
      }
      // 更新店铺品牌名称
      builder = new gen.sequelizeQueryBuilder()
      let queryObjB = builder.bindTransaction(transactionA).build()
      let [updateRowsB] = await this.xpinModel.XpinShop.update(
        { brand_name: body.brand_name, city: body.city_name },
        queryObjB
      )
      if (updateRowsB !== 1) {
        throw new Error("更新失败")
      }
      // 新增挂车记录
      builder = new gen.sequelizeQueryBuilder()
      let queryObjC = builder.bindTransaction(transactionA).build()
      await this.xpinModel.XpinShopcaseRecord.create(
        { author_id: body.author_id, goods_id: body.gid },
        queryObjC
      )

      transactionA.commit()
      return { success: true }
    } catch (e) {
      transactionA.rollback()
      return { success: false, msg: e.message }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

对应的sql

START TRANSACTION;
UPDATE `kbd_xuanpin`.`xpin_shop` SET `nick_name`=1+1,`updated_at`=? WHERE (`id` = 1)
UPDATE `kbd_xuanpin`.`xpin_shop` SET `brand_name`=?,`city`=?,`updated_at`=? WHERE (`id` = 1)
INSERT INTO `kbd_xuanpin`.`xpin_shopcase_record` (`id`,`author_id`,`channel`,`created_at`,`goods_id`,`goods_promotion_id`,`is_delete`,`issue_company_id`,`operate_user_id`,`position`,`reason`,`recommend_user_id`,`result`,`share_id`,`shopcase_company_id`,`site_info_id`,`source`,`sum_pay_amount`,`terminal`,`user_id`,`visited_at`) VALUES (DEFAULT,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);
COMMIT;
1
2
3
4
5

# 排序,分组,having

配置json

{
  "model": "compassModel.ProductDayData",
  "method": "findAll",
  "pagination": {
    "paginate": true
  },
  "params": {
    "attributes": ["title", "max(id)"],
    "order":[["id","desc"]],
    "group": ["id"],
    "having": "id > 10"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

生成的js

builder
  .select("title", builder.raw("max(id)"))
  .orderBy("id", "desc")
  .groupBy("id")
  .havingRaw("id > 10")
  .bind(query)
  .build()
1
2
3
4
5
6
7

# relateOne查询

配置json

{
  "method": "relateOne",
  "model": "xpinModel.XpinShop",
  "localField": "id",
  "fromField": "shop_id",
  "as": "shop",
  "attributes": ["shop_name", "id"],
  "where": [
    {"id": {"op": ">","value": 0}}
  ]
}
1
2
3
4
5
6
7
8
9
10
11

生成的js

await this.relateOne({
  data: result,
  model: this.xpinModel.XpinShop,
  id_name: "shop_id",
  over_id: "id",
  obj_name: "shop",
  attributes: ["shop_name", "id"],
  where: new gen.sequelizeQueryBuilder().where("id", ">", 0).bind(query).build().where
})
1
2
3
4
5
6
7
8
9

对于的sql

SELECT `shop_name`, `id` FROM `xpin_shop` AS `XpinShop` WHERE (`XpinShop`.`id` > 0) AND `XpinShop`.`id` IN (19338, 2405, 19328);
1

# relateMany查询

json配置


  {
    "method": "relateMany",
    "model": "xpinModel.XpinShop",
    "localField": "id",
    "fromField": "shop_id",
    "as": "shop",
    "attributes": ["shop_name", "id"],
    "where": [
      {"id": {"op": ">","value": 0}}
    ]
  }
1
2
3
4
5
6
7
8
9
10
11
12

生成的js

await this.relateMany({
  data: result,
  model: this.xpinModel.XpinShop,
  id_name: "id",
  over_id: "shop_id",
  obj_name: "shop",
  attributes: ["shop_name", "id"],
  where: new gen.sequelizeQueryBuilder().where("id", ">", 0).bind(query).build().where
})
1
2
3
4
5
6
7
8
9

对应的sql

SELECT `shop_name`, `id` FROM `xpin_shop` AS `XpinShop` WHERE (`XpinShop`.`id` > 0) AND `XpinShop`.`id` IN (19338, 2405, 19328);
1