AppMaster 提供了广泛的数据库处理功能。例如,使用Search块,您可以找到必要的数据,将相关表附加到它,以正确的顺序对其进行排序等。但是,在某些情况下,这可能还不够,然后SQL Exec块来救援。它允许您使用 SQL 的全部功能来运行任何数据库查询。
让我们使用包含书籍目录的数据库示例来考虑该块的操作。
让我们做一些准备工作。有必要创建一个业务流程,以最简单的形式允许发送请求并接收其结果。
您还需要创建一个端点来允许您访问此业务流程。
在初始阶段,这应该足够了。您可以发布您的应用程序并继续进行测试。为此,使用 Swagger 非常方便,它是在发布时自动创建的。
我们使用一个简单的查询来请求数据库中的所有书籍。
从 public.book 中选择 *
请注意,表本身(与数据库编辑器中创建的所有其他表一样)具有指示模式的前缀 - public。
您可以验证请求是否已成功完成并已收到结果。
但问题是,很难以这种形式感知答案。一种可能的解决方案是稍微修改请求并仅保留其中必要的字段,例如书名和页数。此外,设置一个限制是合理的,不是从数据库中请求所有书籍,而是将自己限制为十本。
从 public.book 中选择名称、页数 LIMIT 10
好多了,但仍然不适合实际使用。毕竟,在业务流程中,您不仅需要接收请求,还需要对其结果执行某些操作。为此,仅仅获得文本形式的结果是不够的;您需要将其变成适合进一步使用的模型。
为此,让我们回到业务流程并对其进行一些改进。在最后的块中,我们将添加一个新变量 - 书籍模型数组。
您还需要一个块,用于将收到的请求结果 JSON 转换为模型。将 JSON 反序列化为模型。
让我们重复之前的请求,并确保结果变得更加适合视觉感知和 BP 中的进一步使用。
现在,我们可以继续讨论更复杂的逻辑。让我们创建一个业务流程:
- 接收书名作为输入。
- 确定它属于哪个类别(流派)。
- 返回同一类别中的 3 本书作为结果(在这种情况下,请求中的书不应在其中)
为此,我们将创建一个新的业务流程,将使用标准块的搜索和 SQL 查询的使用结合起来。
第一个块是通过书名查找一本书,并确定它属于哪个类别。为此,我们使用带有以下参数的搜索块:
- _With = Categories - 除了书籍本身之外,查询结果还需要来自关联类别表的信息。
- _Limit = 1 - 只需要找到一本书。
- _Ilike = False - 名称必须与请求的名称完全匹配。
- 名称 - 书名索引,从 Start 块传递。
使用索引为 0 的 Array Element 块,我们从结果中取出第一本书(也是唯一一本)。
一本书可以同时属于几个不同的类别,在这种情况下,其中任何一个类别都适合我们。可以使用随机元素块随机选择
之后,我们拥有了所有必要的数据,剩下的就是创建请求本身,它可能如下所示:
SELECT * FROM public.book WHERE id IN (SELECT rel1_id FROM public.book_categorys_category_books_pivot WHERE book_categorys_category_books_pivot.rel2_id = X) AND id <> Y ORDER BY random() LIMIT 3
其中X是图书类别的id,Y是图书本身的id。
请注意,该查询包含一个子查询。首先,从book_categorys_category_books_pivot表(用于存储两个表之间的关系信息)中找到与所选类别对应的所有图书标识符。此后,执行一个查询,查找与指定范围匹配的随机 3 本书,不包括书籍 ID,其书名最初传递给业务流程。
要更详细地研究项目数据库结构,您可以使用“部署计划”设置中的“打开数据库”按钮。
它将允许您在编辑器中打开数据库并直接访问查看和编辑数据。但是,您应该小心并考虑到这样一个事实:在编辑器中更改数据结构本身将导致无法进一步发布项目。
让我们回到创建业务流程。有必要完成请求的编译,为此,将书籍和类别 ID 从整数转换为字符串,并使用 Concat Strings (Multiple) 块组装最终请求。
最后一步是执行查询,将结果转换为模型,并将其作为查询结果发送到 End 块。
您可以保存更改、创建端点、发布项目并验证请求是否正常工作。在本例中,使用一个具有复杂复合查询的 SQL Exec 块来替换许多其他块并简化业务流程的结构。
SQL Exec 块的用途不仅限于数据检索,还可以用于多种场景。让我们仔细看看更多的选项。
- 统计id=X的书的评论数
从 public.comment 中选择 COUNT(id),其中 book_id = X - 计算一本书的平均评分,考虑评论中给出的所有评分:
从 public.comment WHERE book_id = X 中选择 AVG(rate) - 删除2023年之前写入的所有评论(例如可以用于快速清除日志)。
从 public.comment 删除*,其中created_at <'2023-01-01'
总之,值得注意的是,为了提高安全性,在 SQL Exec 块中添加了一个过滤器,以防止可能导致架构更改的危险操作。
如果应用程序托管在 AppMaster 服务器上,则过滤器将禁用 TABLE|COLUMN|INDEX|CONSTRAINT|SEQUENCE|SCHEMA|DATABASE 的 CREATE/ALTER/DROP/TRUNCATE。在本地托管时 - 默认情况下,任何请求都可以不受限制地使用。