配置SQL代码调用(Configured SQL Invocation),即client端通过http/https
直接调用后端配置好的SQL
。该功能适用于复杂的业务场景,开发人员可以将复杂的SQL
写到配置文件中,后台通过传进来的名称与参数调用。CSI是DbRESTFul的核心功能之一。
[TOC]
配置SQL代码调用的代码文件以json
格式存储,通常,该配置代码文件存放在服务项目的CSI目录,也可以通过该项目的根目录下的config.json
文件中指定。
{
……
"CSIPath": "CSI/"
……
}
CSI的详细定义,请参考Wicture.DbRESTFul
项目中Schema
目录下的csi-schema.json
文件。它的主要结构如下:
{
"name": "",
"code": "",
"resultSet": "",
"queryOnly": true,
"requiredTransaction": false,
"middleWares": {}
}
假设我们需要查询指定项目下的所有接口定义。 调用参数包括:
name | type | required | note |
---|---|---|---|
projectId | int | yes | The project Id |
module | string | no | The module name |
keyword | string | no | The keyword for searching (name, module, owner, title) |
orderBy | string | no | Sorting |
pageIndex | int | yes | pageIndex for pagination |
pageSize | int | yes | pageSize for pagination |
对应的CSI可能是这样定义的:
{
"name": "list_api_for_project",
"code": "SELECT * FROM api WHERE projectId = @projectId [AND `module`=@module] [AND (`name` LIKE CONCAT('%',@keyword,'%') OR `module` LIKE CONCAT('%',@keyword,'%') OR `owner` LIKE CONCAT('%',@keyword,'%') OR `title` LIKE CONCAT('%',@keyword,'%') )] @orderBy LIMIT @pageStart, @pageSize;",
"resultSet": "M",
"queryOnly": true,
"requiredTransaction": false,
"middleWares": {
"pagination": {
"size": "pageSize",
"count": "totalCount",
"page": "pageIndex"
},
"defaults": {
"orderBy": "id DESC"
},
"replace": [ "orderBy" ]
}
}
返回结果请参考隐式对象代码
说明:
name
: 必须全局唯一,即整个应用程序级别的唯一性,否则应用程序启动加载时会抛异常。code
为要执行的SQL语句,参数通过@parameterName
的形式声名。- 对于可选参数,将条件放入
[]
中,SQL被执行前,如果未指定该参数,则该条件将被忽略。"resultSet": "M"
: 此CSI返回结果集是一个集合。"queryOnly": true
: 该CSI将通过只读连接执行。"requiredTransaction": false
: 该CSI不启用事务。- 该CSI将通过
pagination
Middleware来作分页操作,具体请参考Middleware
部分的说明。这里的pageIndex
与pageSize
参数就是为了使用该Middleware。- 该CSI默认以
id DESC
排序,调用者也可以指定排序方式。- 因
orderBy
为特殊定义,Dapper并不能像SQL参数一样处理,所以需要通过replace
作执行前处理。- 对于所有参数都是可选参数的情况,
where
后面需要加一个1=1
的恒成立条件。
单次执行代码,即:code
为字符串类型的SQL语句。如:
{
"name": "GetApi",
"code": "SELECT * FROM api WHERE id = @id;",
"resultSet": "S",
"queryOnly": true,
"requiredTransaction": false
}
通过DbRESTFul
标准化输入的结果为:
{
"statusCode": "200",
"errorMessage": "",
"data": {
"id": 23,
"name": "GetUserInfo",
……
}
}
对象型代码,即:code
为object
对象,即,key
: sql
。,且。如:code
的定义为:
{
"name": "CreateCart",
"code": {
"user": "SELECT name, phone FROM user WHERE userId = @userId",
"order": "UPDATE order SET status = @status WHERE orderId = @orderId;SELECT @orderId AS orderId",
"cart": "INSERT INTO cart(sn, ammount, userId) VALUES(@sn, @ammount, @userId);SELECT LAST_INSERT_ID() AS cartId;"
},
"resultSet": "S,S,S",
"queryOnly": false,
"requiredTransaction": true
}
通过DbRESTFul
标准化输入的结果可能是:
{
"statusCode": "200",
"errorMessage": "",
"data": {
"user": { "name": "dawson", "phone": 13545245245 },
"order": { "orderId": 23 },
"cart": { "cartId": 324 }
}
}
说明:
- 返回结果有多个时,通过
"resultSet": "S,S,S"
指定集合类型。- 执行的结果对象与
code
定义一一对应。- 如果
"requiredTransaction": true
的话,整个code
对象将被放在一个trancaction
内执行。
隐式对象代码,如上面示例说明
的例子,code
虽然是一个字符串,但因为使用了pagination
Middleware,实际上也会以对象的方式执行。其它返回结果如下:
{
"statusCode": "200",
"errorMessage": "",
"data": {
"items": [
{ "id": 32, "name": "GetUserInfo", …… },
{ "id": 33, "name": "UpdateUserInfo", …… },
{ "id": 34, "name": "DeleteUserInfo", …… },
],
"pagination": {
"pageIndex": 2,
"pageSize": 10,
"totalCount": 69
}
}
}