aaron-lin / json-schema-sql-builder
一个用于从JSON Schema构建SQL查询的PHP库
v1.0.1
2023-07-12 09:05 UTC
Requires
- php: >=7.4
README
这是一个简单的工具,可以从JSON Schema生成SQL DDL语句。
安装
$ composer require aaron-lin/json-schema-sql-builder
用法
从JSON Schema构建SELECT语句
例如,JSON Schema如下
{ "$schema": "https://json-schema.fullstack.org.cn/draft-06/schema#", "@table": "products", "@id": "id", "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "_type_name": { "type": "string" }, "_weight": { "type": "object", "properties": { "weight": { "type": "number" }, "weight_unit": { "type": "string", "enum": [ "g", "kg" ] } } }, "_bids": { "type": "array", "@table": "bids", "@joinId": "product_id", "@id": "id", "@orderBy": "time DESC", "items": { "type": "object", "properties": { "id": { "type": "string" }, "price": { "type": "number" }, "time": { "type": "string", "format": "date-time" } } } } } }
使用以下代码执行SQL SELECT查询
use Lin\JsonSchemaSqlBuilder\Storage; use Lin\JsonSchemaSqlBuilder\SelectSQLBuilder; $SchemaURI = 'path/to/schema.json#'; $DSN = 'mysql:host=db;dbname=test;charset=utf8mb4'; $DB = new \PDO($DSN, 'test', 'test'); try { Storage::SetSchemaFromURI($SchemaURI); } catch (\Exception $e) { echo $e->getMessage(); exit; } Storage::AddSelectExpression($SchemaURI . '#/properties/_type_name', '(SELECT name FROM product_types WHERE product_types.id = products.type_id LIMIT 1)'); Storage::AddSelectExpression($SchemaURI . '#/properties/_weight/properties/weight', 'products.weight'); Storage::AddSelectExpression($SchemaURI . '#/properties/_weight/properties/weight_unit', 'products.weight_unit'); $Builder = new SelectSQLBuilder($SchemaURI, $DB); $Builder->SetSelectExpressions() ->AddWhere("products.keywords like :keywords", ['keywords' => '%apple%']) ->AddOrderBy('products.price', 'DESC') ->SetLimit(10) ->SetOffset(0); $Result = $Builder->Execute(); echo json_encode($Result, JSON_PRETTY_PRINT); // [ // { // "id": "1", // "name": "Apple", // "_type_name": "Fruit", // "_weight": { // "weight": "100.00", // "weight_unit": "g" // }, // "_bids": [ // { // "id": "7", // "price": "400", // "time": "2018-01-04 00:00:00" // }, // { // "id": "5", // "price": "300", // "time": "2018-01-03 00:00:00" // }, // { // "id": "3", // "price": "200", // "time": "2018-01-02 00:00:00" // }, // { // "id": "1", // "price": "100", // "time": "2018-01-01 00:00:00" // } // ] // } // ]
如您所见,在初始化JSON schema存储后,您可以添加选择表达式以间接对应属性(直接属性将自动添加到选择表达式,格式为SelectSQLBuilder::Build
方法构建SQL SELECT语句。更多详情请参考测试脚本,您也可以在测试目录中找到数据库模式和数据。
从JSON Schema构建INSERT/UPDATE语句
例如,JSON Schema如下
{ "$schema": "https://json-schema.fullstack.org.cn/draft-06/schema#", "@table": "products", "@id": "id", "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "_type_name": { "type": "string", "readonly": true }, "_weight": { "type": "object", "properties": { "weight": { "type": "number" }, "weight_unit": { "type": "string", "enum": [ "g", "kg" ] } } }, "_bids": { "type": "array", "@table": "bids", "@joinId": "product_id", "@id": "id", "@orderBy": "time DESC", "items": { "type": "object", "properties": { "id": { "type": "string" }, "price": { "type": "number" }, "time": { "type": "string", "format": "date-time" } } } } } }
数据如下
{ "id": "1", "name": "Apple", "_type_name": "Fruit", "_weight": { "weight": "100.00", "weight_unit": "g" }, "_bids": [ { "id": "7", "price": "400", "time": "2018-01-04 00:00:00" }, { "id": "5", "price": "300", "time": "2018-01-03 00:00:00" }, { "id": "3", "price": "200", "time": "2018-01-02 00:00:00" }, { "id": "1", "price": "100", "time": "2018-01-01 00:00:00" } ] }
使用以下代码执行SQL INSERT/UPDATE查询
use Lin\JsonSchemaSqlBuilder\Storage; use Lin\JsonSchemaSqlBuilder\UpsertSQLBuilder; $SchemaURI = __DIR__ . '/schema.json#'; $DSN = 'mysql:host=db;dbname=test;charset=utf8mb4'; $DB = new \PDO($DSN, 'test', 'test'); try { Storage::SetSchemaFromURI($SchemaURI); } catch (\Exception $e) { echo $e->getMessage(); exit; } Storage::AddSelectExpression($SchemaURI . '#/properties/_weight/properties/weight', 'products.weight'); Storage::AddSelectExpression($SchemaURI . '#/properties/_weight/properties/weight_unit', 'products.weight_unit'); $Builder = new UpsertSQLBuilder($SchemaURI, $DB, $Data); $Builder->SetAssignmentList(); $ResultCount = $Builder->Execute(); echo $ResultCount; // for every new rows added, the return value is 1, // for every existing rows updated, the return value is 2. // data contains 1 row in products, 4 rows in bids, // therefore, if data are all new rows, the return value is 5, // or data are all existing rows, the return value is 10
对于每新增的行,UpsertSQLBuilder::Execute
的返回值为1
,对于每更新的现有行,返回值为2
。更多详情请参考测试脚本,您也可以在测试目录中找到数据库模式和数据。