# aqoeous-graphql **Repository Path**: feedback/aqoeous-graphql ## Basic Information - **Project Name**: aqoeous-graphql - **Description**: 根据GraphQL的思想设计的java后台接口方案.. 每个接口都是一个查询器,比如获得一个班级的列表的接口是一个班级查询器, 获取用户列表的接口是一个用户查询器. 而每个查询器直接都可让另一个查询器作为查询子表,也可以任何一个查询器作为统计查询 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 3 - **Created**: 2021-08-19 - **Last Updated**: 2021-08-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # aqoeous-graphql ## 介绍 根据GraphQL的思想设计的java后台接口方案.. 每个接口都是一个查询器,比如获得一个班级的列表的接口是一个班级查询器, 获取用户列表的接口是一个用户查询器. 而每个查询器直接都可让另一个查询器作为查询子表,也可以任何一个查询器作为统计查询 ## 语法,名称定义 QO: Query Object 查询对象,最前层定义的一些参数或者对SO的处理方式,我们称之为'查询器' SO: Search Object 搜索对象,用于定义mybatis检索数据库时的过滤器和查询方式 支持跨库查询,一个QO相当于是查询一个表,对该表设置过滤条件,和关联查询时用到的过滤条件 ### 使用方法 启动服务后访问 http://localhost:8080/index 测试 org.shoukaiseki.aqoeous.service.impl.ItemQueryServiceImpl 和 org.shoukaiseki.aqoeous.service.impl.ShopQueryServiceImpl 是定义QO查询器 ### 语法说明 ```javascript [ //QO查询器,按顺序依次查询 { //第一个QO查询器 //[返回值的自定义名称,默认与qoName相同] "resultName": "shopQO", //[QO查询器名称] "qoName": "shopQO", "qoJson": { // 这里为查询使用的参数(包含默认的分页参数名,自定义的过滤器名称) "pageNum": 1, // 每页条数,当pageSize为-1时,获取结果的总条数 "pageSize": 10, "shopIdList":[1,2] }, // 查询子级 "qoChilds": [{ // 子级的QO名称 "qoName": "itemQO", "qoJson": { // 子级的参数定义 "pageNum": 1, "pageSize": 10 }, // 与主表关联关系 "relationships": [ { // 子级的参数名称,最后会将该值设置到子级的qoJson中 "paramName": "shopIdList", // 数据来源,根据主表返回值的 shopId 属性,统计为数组设置到子级的 shopIdList 参数中 "sourceDatas": [ "shopId" ] } ] }] }, { // 第二个主数据集QO查询器定义 "resultName": "itemQO", "qoName": "itemQO", "qoJson": { "pageNum": 1, "pageSize": 999 }, // 根据之前的QO查询器进行关联查询 "relationships": [ { //该查询器的参数名 "paramName": "shopIdList", "sourceDatas": [ //根据返回值data中的数据,展现方式进行反射获取对应的值,相当于 resultModel.getData().get("shopQO").get("shopId"); //然后将所有获取到的值放到Set当中,再讲该Set赋值与参数 shopIdList "shopQO.shopId" ] } ] } ] ``` #### 增加的mergeParent功能 ```javascript [ { "resultName": "shopQO", "qoName": "shopQO", "qoJson": { "pageNum": 1, "pageSize": 10 }, "qoChilds": [ { //将数据合并到父级,该qo在子级时才生效,合并到父级使用的字段名为 resultName //子级无关联查询时才能使用 "mergeParent": true, //mergeParent 为 true 时生效,适合无分页 //将首条记录合并到父级,该qo在子级时才生效,合并到父级使用的字段名为 resultName "listFirstMergeParent": false, //mergeParent 为 true 时生效,适合无分页 //listFirstMergeParent 启用后该功能失效 "listMergeParent": false, "resultName": "virtualItemList", "qoName": "itemQO", "qoJson": { "pageNum": 1, "pageSize": 999999 }, "relationships": [ { "paramName": "shopIdList", "sourceDatas": [ "shopId" ] } ] } ] } ] ``` ### 演示 shop位于数据库aqoeous_db1,item位于数据库aqoeous_db2 #### 联合查询 ##### 店铺及旗下商品 ```json [ { "resultName": "shopQO", "qoName": "shopQO", "qoJson": { "pageNum": 1, "pageSize": 10 }, "qoChilds": [ { "qoName": "itemQO", "qoJson": { "pageNum": 1, "pageSize": 10 }, "relationships": [ { "paramName": "shopIdList", "sourceDatas": [ "shopId" ] } ] } ] } ] ``` 返回值: ```json { "data": { "shopQO": { "list": [ { "aqoeousChild": { "itemQO": { "list": [ { "itemId": 1, "name": "五香鹅蛋", "shopId": 1 }, { "itemId": 3, "name": "家养鸡蛋", "shopId": 1 }, { "itemId": 5, "name": "农家鸭蛋", "shopId": 1 } ], "total": 3 } }, "name": "茶叶蛋", "shopId": 1 }, { "aqoeousChild": { "itemQO": { "list": [ { "itemId": 2, "name": "西瓜", "shopId": 2 }, { "itemId": 4, "name": "火龙果", "shopId": 2 }, { "itemId": 6, "name": "香蕉", "shopId": 2 } ], "total": 3 } }, "name": "水果超市", "shopId": 2 }, { "aqoeousChild": { "itemQO": { "list": [ { "itemId": 7, "name": "臭豆腐", "shopId": 3 }, { "itemId": 8, "name": "豆干", "shopId": 3 }, { "itemId": 9, "name": "油豆腐", "shopId": 3 } ], "total": 3 } }, "name": "祖名豆制品", "shopId": 3 } ], "total": 3 } }, "msg": null, "status": 0, "statusParams": null } ``` ##### 店铺及旗下商品,高效查询[数据需客户端处理] 这里展示的是shopId为1和2的数据,查询语法为并列关系,先查询的shopQO,再根据shopQO中的返回值查询itemQO[对数据库只查询2次] ```json [ { "resultName": "shopQO", "qoName": "shopQO", "qoJson": { "pageNum": 1, "pageSize": 10, "shopIdList": [ 1, 2 ] } }, { "resultName": "itemQO", "qoName": "itemQO", "qoJson": { "pageNum": 1, "pageSize": 10, "shopIdList": [ 1, 2 ] }, "relationships": [ { "paramName": "shopIdList", "sourceDatas": [ "shopQO.shopId" ] } ] } ] ``` 返回值: ```json { "data": { "shopQO": { "list": [ { "name": "茶叶蛋", "shopId": 1 }, { "name": "水果超市", "shopId": 2 } ], "total": 2 }, "itemQO": { "list": [ { "itemId": 1, "name": "五香鹅蛋", "shopId": 1 }, { "itemId": 2, "name": "西瓜", "shopId": 2 }, { "itemId": 3, "name": "家养鸡蛋", "shopId": 1 }, { "itemId": 4, "name": "火龙果", "shopId": 2 }, { "itemId": 5, "name": "农家鸭蛋", "shopId": 1 }, { "itemId": 6, "name": "香蕉", "shopId": 2 } ], "total": 6 } }, "msg": null, "status": 0, "statusParams": null } ``` ##### 店铺及旗下商品总数 子级item中的pageSize设置为-1即可,其中的total就是item总数 ```json [ { "resultName": "shopQO", "qoName": "shopQO", "qoJson": { "pageNum": 1, "pageSize": 10 }, "qoChilds": [ { "qoName": "itemQO", "qoJson": { "pageNum": 1, "pageSize": -1 }, "relationships": [ { "paramName": "shopIdList", "sourceDatas": [ "shopId" ] } ] } ] } ] ``` 返回值: ```json { "data": { "shopQO": { "list": [ { "aqoeousChild": { "itemQO": { "list": [], "total": 3 } }, "name": "茶叶蛋", "shopId": 1 }, { "aqoeousChild": { "itemQO": { "list": [], "total": 3 } }, "name": "水果超市", "shopId": 2 }, { "aqoeousChild": { "itemQO": { "list": [], "total": 3 } }, "name": "祖名豆制品", "shopId": 3 } ], "total": 3 } }, "msg": null, "status": 0, "statusParams": null } ``` ##### 商品主表,同时需要查出所属店铺名称 可以看出,很多商品是同一个店铺的,这种情况下使用高效查询数据量会少很多 ```json [ { "resultName": "itemQO", "qoName": "itemQO", "qoJson": { "pageNum": 1, "pageSize": 10 }, "qoChilds": [ { "qoName": "shopQO", "qoJson": { "pageNum": 1, "pageSize": 1 }, "relationships": [ { "paramName": "shopIdList", "sourceDatas": [ "shopId" ] } ] } ] } ] ``` 返回值: ```json { "data": { "itemQO": { "list": [ { "itemId": 1, "aqoeousChild": { "shopQO": { "list": [ { "name": "茶叶蛋", "shopId": 1 } ], "total": 1 } }, "name": "五香鹅蛋", "shopId": 1 }, { "itemId": 2, "aqoeousChild": { "shopQO": { "list": [ { "name": "水果超市", "shopId": 2 } ], "total": 1 } }, "name": "西瓜", "shopId": 2 }, { "itemId": 3, "aqoeousChild": { "shopQO": { "list": [ { "name": "茶叶蛋", "shopId": 1 } ], "total": 1 } }, "name": "家养鸡蛋", "shopId": 1 }, { "itemId": 4, "aqoeousChild": { "shopQO": { "list": [ { "name": "水果超市", "shopId": 2 } ], "total": 1 } }, "name": "火龙果", "shopId": 2 }, { "itemId": 5, "aqoeousChild": { "shopQO": { "list": [ { "name": "茶叶蛋", "shopId": 1 } ], "total": 1 } }, "name": "农家鸭蛋", "shopId": 1 }, { "itemId": 6, "aqoeousChild": { "shopQO": { "list": [ { "name": "水果超市", "shopId": 2 } ], "total": 1 } }, "name": "香蕉", "shopId": 2 }, { "itemId": 7, "aqoeousChild": { "shopQO": { "list": [ { "name": "祖名豆制品", "shopId": 3 } ], "total": 1 } }, "name": "臭豆腐", "shopId": 3 }, { "itemId": 8, "aqoeousChild": { "shopQO": { "list": [ { "name": "祖名豆制品", "shopId": 3 } ], "total": 1 } }, "name": "豆干", "shopId": 3 }, { "itemId": 9, "aqoeousChild": { "shopQO": { "list": [ { "name": "祖名豆制品", "shopId": 3 } ], "total": 1 } }, "name": "油豆腐", "shopId": 3 } ], "total": 9 } }, "msg": null, "status": 0, "statusParams": null } ``` ##### 商品主表[高效查询] 之前方式的查询是item中有几条数据,就查了几次shop表中的数据.而高效查询是先根据返回值中itemQO的shopId,然后作为shopIdList参数去查shopQO得到最终的数据集 ```json [ { "resultName": "itemQO", "qoName": "itemQO", "qoJson": { "pageNum": 1, "pageSize": 10 } }, { "resultName": "shopQO", "qoName": "shopQO", "qoJson": { "pageNum": 1, "pageSize": 10 }, "relationships": [ { "paramName": "shopIdList", "sourceDatas": [ "itemQO.shopId" ] } ] } ] ``` 返回值: ```json { "data": { "itemQO": { "list": [ { "itemId": 1, "name": "五香鹅蛋", "shopId": 1 }, { "itemId": 2, "name": "西瓜", "shopId": 2 }, { "itemId": 3, "name": "家养鸡蛋", "shopId": 1 }, { "itemId": 4, "name": "火龙果", "shopId": 2 }, { "itemId": 5, "name": "农家鸭蛋", "shopId": 1 }, { "itemId": 6, "name": "香蕉", "shopId": 2 }, { "itemId": 7, "name": "臭豆腐", "shopId": 3 }, { "itemId": 8, "name": "豆干", "shopId": 3 }, { "itemId": 9, "name": "油豆腐", "shopId": 3 } ], "total": 9 }, "shopQO": { "list": [ { "name": "茶叶蛋", "shopId": 1 }, { "name": "水果超市", "shopId": 2 }, { "name": "祖名豆制品", "shopId": 3 } ], "total": 3 } }, "msg": null, "status": 0, "statusParams": null } ``` #### 分页查询 ##### shopList-第1页 每页1条数据 ```json [ { "resultName": "shopQO", "qoName": "shopQO", "qoJson": { "pageNum": 1, "pageSize": 1 } } ] ``` 返回值: ```json { "data": { "shopQO": { "list": [ { "name": "茶叶蛋", "shopId": 1 } ], "total": 3 } }, "msg": null, "status": 0, "statusParams": null } ``` ##### shopList-第2页 ```json [ { "resultName": "shopQO", "qoName": "shopQO", "qoJson": { "pageNum": 2, "pageSize": 1 } } ] ``` 返回值: ```json { "data": { "shopQO": { "list": [ { "name": "水果超市", "shopId": 2 } ], "total": 3 } }, "msg": null, "status": 0, "statusParams": null } ``` ##### itemList-第1页 ```json [ { "resultName": "itemQO", "qoName": "itemQO", "qoJson": { "pageNum": 1, "pageSize": 3 } } ] ``` 返回值: ```json { "data": { "itemQO": { "list": [ { "itemId": 1, "name": "五香鹅蛋", "shopId": 1 }, { "itemId": 2, "name": "西瓜", "shopId": 2 }, { "itemId": 3, "name": "家养鸡蛋", "shopId": 1 } ], "total": 9 } }, "msg": null, "status": 0, "statusParams": null } ``` ##### itemList-第2页 ```json [ { "resultName": "itemQO", "qoName": "itemQO", "qoJson": { "pageNum": 2, "pageSize": 3 } } ] ``` 返回值: ```json { "data": { "itemQO": { "list": [ { "itemId": 4, "name": "火龙果", "shopId": 2 }, { "itemId": 5, "name": "农家鸭蛋", "shopId": 1 }, { "itemId": 6, "name": "香蕉", "shopId": 2 } ], "total": 9 } }, "msg": null, "status": 0, "statusParams": null } ``` #### 筛选查询 ##### shopList-根据主键筛选 ```json [ { "resultName": "shopQO", "qoName": "shopQO", "qoJson": { "pageNum": 1, "pageSize": 10, "shopIdList": [ 2 ] } } ] ``` 返回值: ```json { "data": { "shopQO": { "list": [ { "name": "水果超市", "shopId": 2 } ], "total": 1 } }, "msg": null, "status": 0, "statusParams": null } ``` ##### shopList-名称筛选 名称中既包含'茶'字,也包含'蛋'字 ```json [ { "resultName": "shopQO", "qoName": "shopQO", "qoJson": { "pageNum": 1, "pageSize": 10, "nameList": [ "茶", "蛋" ] } } ] ``` 返回值: ```json { "data": { "shopQO": { "list": [ { "name": "茶叶蛋", "shopId": 1 } ], "total": 1 } }, "msg": null, "status": 0, "statusParams": null } ``` ##### itemList-根据店铺筛选1 ```json [ { "resultName": "itemQO", "qoName": "itemQO", "qoJson": { "pageNum": 1, "pageSize": 10, "shopIdList": [ 1 ] } } ] ``` 返回值: ```json { "data": { "itemQO": { "list": [ { "itemId": 1, "name": "五香鹅蛋", "shopId": 1 }, { "itemId": 3, "name": "家养鸡蛋", "shopId": 1 }, { "itemId": 5, "name": "农家鸭蛋", "shopId": 1 } ], "total": 3 } }, "msg": null, "status": 0, "statusParams": null } ``` ##### itemList-根据店铺筛选2 ```json [ { "resultName": "itemQO", "qoName": "itemQO", "qoJson": { "pageNum": 1, "pageSize": 10, "shopIdList": [ 2 ] } } ] ``` 返回值: ```json { "data": { "itemQO": { "list": [ { "itemId": 2, "name": "西瓜", "shopId": 2 }, { "itemId": 4, "name": "火龙果", "shopId": 2 }, { "itemId": 6, "name": "香蕉", "shopId": 2 } ], "total": 3 } }, "msg": null, "status": 0, "statusParams": null } ``` ##### itemList-名称筛选 ```json [ { "resultName": "itemQO", "qoName": "itemQO", "qoJson": { "pageNum": 1, "pageSize": 10, "nameList": [ "蛋" ] } } ] ``` 返回值: ```json { "data": { "itemQO": { "list": [ { "itemId": 1, "name": "五香鹅蛋", "shopId": 1 }, { "itemId": 3, "name": "家养鸡蛋", "shopId": 1 }, { "itemId": 5, "name": "农家鸭蛋", "shopId": 1 } ], "total": 3 } }, "msg": null, "status": 0, "statusParams": null } ```