如何正确组织 Knex 查询?
How to properly organize Knex queries?
我陷入了 "so many folders" 陷阱,发现很难在控制器文件夹中跟踪我的所有 Knex 查询。只是给你一个想法 - 我有超过 140 个不同的 js 文件,只有查询。
这是我的 CONTROLLERS 文件夹的示例,让您了解它有多乱:
- 查询
- 标准
- getOpenProjects.js
- getClosedProjects.js
- createNewProjects.js
- getProjectsChart.js
- getClosedProjectsChart.js
- ...(还有 41 个文件)
- 图表
- lineChartOfTechs.js
- delayedTechs.js
- overallPie.js
- ... (还有 11 个文件)
- 任务
- getTasksByTech.js
- delayedTasks.js
- tasksColumnTask.js
- ... (35个文件)
如您所见,我尝试将其保存在文件夹中,但在我编写代码时 - 我只是将其命名为文件以供参考。在每个文件夹中搜索我需要的确切文件越来越累人。
我尝试使用 Bookshelf JS,但有太多复杂的左连接 - 我最终放弃并回到了 KnexJS。 Bookshelf 频道的一些答案最终告诉我使用 Bookshelf Knex RAW 命令。我想 - 如果我要回到 Knex - 我最好坚持使用它而不是添加另一个模块。
无论如何 - 问题是 - 我如何正确地构建它以便我可以轻松找到我正在寻找的东西?你会如何在你的项目中做到这一点?有什么好的组织工具可以保存查询或 Knex 代码吗?
我们在 knex
之上使用 objection.js 作为 ORM(反对使用 knex 作为其查询构建器和用于迁移)并且大部分直接在我们的控制器中编写我们的查询(我知道,有些人认为这是异端)。
由于大多数查询只使用一次,因此将每个查询都包装到某个单独的函数中是没有用的。它只会使重构和更改代码变得更加困难,并且如果稍后更改修改查询含义但函数名称不固定等,可能会以错误命名的查询函数结束。
所以对于简单的 one-time 查询,我们直接这样做:
let person = await Person.query().findById(personId);
如果在多个地方需要一些复杂的查询,我们将其写成相应模型的方法class。
例如,如果查询 returns Person
模型,则该查询将写入 Person
class。当然,这些基本规则会有例外,但可以单独考虑所有这些情况如何处理它们。
在我们当前的项目中,我们有大约 40 个模型,并且在尝试弄清楚如何组织我们的查询时没有遇到任何问题。
编辑:
我确实错过了原始答案中的情况,我们有对多个表执行多个查询的方法。
通常我们将它们包装到一些单独的服务 API class 中,它清楚地说明它为应用程序提供了哪种功能,我们将 API 注入到需要的控制器中它。
我陷入了 "so many folders" 陷阱,发现很难在控制器文件夹中跟踪我的所有 Knex 查询。只是给你一个想法 - 我有超过 140 个不同的 js 文件,只有查询。
这是我的 CONTROLLERS 文件夹的示例,让您了解它有多乱:
- 查询
- 标准
- getOpenProjects.js
- getClosedProjects.js
- createNewProjects.js
- getProjectsChart.js
- getClosedProjectsChart.js
- ...(还有 41 个文件)
- 图表
- lineChartOfTechs.js
- delayedTechs.js
- overallPie.js
- ... (还有 11 个文件)
- 任务
- getTasksByTech.js
- delayedTasks.js
- tasksColumnTask.js
- ... (35个文件)
如您所见,我尝试将其保存在文件夹中,但在我编写代码时 - 我只是将其命名为文件以供参考。在每个文件夹中搜索我需要的确切文件越来越累人。
我尝试使用 Bookshelf JS,但有太多复杂的左连接 - 我最终放弃并回到了 KnexJS。 Bookshelf 频道的一些答案最终告诉我使用 Bookshelf Knex RAW 命令。我想 - 如果我要回到 Knex - 我最好坚持使用它而不是添加另一个模块。
无论如何 - 问题是 - 我如何正确地构建它以便我可以轻松找到我正在寻找的东西?你会如何在你的项目中做到这一点?有什么好的组织工具可以保存查询或 Knex 代码吗?
我们在 knex
之上使用 objection.js 作为 ORM(反对使用 knex 作为其查询构建器和用于迁移)并且大部分直接在我们的控制器中编写我们的查询(我知道,有些人认为这是异端)。
由于大多数查询只使用一次,因此将每个查询都包装到某个单独的函数中是没有用的。它只会使重构和更改代码变得更加困难,并且如果稍后更改修改查询含义但函数名称不固定等,可能会以错误命名的查询函数结束。
所以对于简单的 one-time 查询,我们直接这样做:
let person = await Person.query().findById(personId);
如果在多个地方需要一些复杂的查询,我们将其写成相应模型的方法class。
例如,如果查询 returns Person
模型,则该查询将写入 Person
class。当然,这些基本规则会有例外,但可以单独考虑所有这些情况如何处理它们。
在我们当前的项目中,我们有大约 40 个模型,并且在尝试弄清楚如何组织我们的查询时没有遇到任何问题。
编辑:
我确实错过了原始答案中的情况,我们有对多个表执行多个查询的方法。
通常我们将它们包装到一些单独的服务 API class 中,它清楚地说明它为应用程序提供了哪种功能,我们将 API 注入到需要的控制器中它。