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