node.js - 使用 pug、Postgres 和适当的 MVC 表达
问题描述
我最近开始使用 Node.js + Express.js(用 pug 生成)+ pg-promise 来处理数据库。
我的第一个目标是从 Postgres(已经设置)获取数据并使用 render 和 pug 漂亮地显示它。假设它是用户表中的用户列表。
在这个宁静的教程中,我学习了如何获取数据并将其以 JSON 格式返回 -它有效。
根据Mozilla 的教程,我分离了我的代码:
- routes/users.js:对于“/”,我调用user_controller.user_list方法(使用router.get)
- controllers/userController.js我已经导出了user_list,我想在其中向模型询问数据并在有结果时调用render
- query.js有点像我的模型?但我不确定。它有 API:通过 promise 连接到 db,并且我将在 Controller 中使用的每个查询都有一个函数。我相信每个表(或任何逻辑实体)应该有一个模型文件,但是在哪里存储 pgp 连接?该文件基于我提到的第一个教程
// query.js(connectionString 已正确设置为我的 postgres) var pgp = require('pg-promise')(options); var db = pgp(connectionString); 函数 getUsers(req, res, next) { db.any('SELECT (user_id, username) FROM public.users ORDER BY user_id ASC LIMIT 1000') .then(函数(数据){ res.json({ 数据: 数据 }); }) .catch(函数(错误){ 返回下一个(错误); }); } 模块.exports = { 获取用户:获取用户 };
这里开始我的问题,因为大多数教程都使用非常模型-db-schema-friendly 的猫鼬,而我所拥有的是简单的 'SELECT ...' 字符串,我传递给 pg-promise 的 any() 函数。因此我没有像 User 这样的模型类。
在userControllers.js中,我不知道如何调用getUsers()来处理其数据。从 getUsers() 返回 JS 对象会很好。
另外:我应该在哪里调用渲染?在控制器中或仅在
db.any(...).then(function (data) { <--here--> })
之前,我还尝试将整个 Postgres 处理嵌入到 Controller 中,但是从 db.any() 我得到了这个数组进行处理:
[{ row: '(1,John)' },{ row: '(2,Amy)' },{ row: '(50,Peter)' } ]
不知道如何从那里开始,因为我可能也失去了我的 API 功能;-)
我正在浏览多个如何处理 MVC 的教程,但通常它们处理 MongoDB 并使用 res.send() 而不是 render() 来满足读者。
解决方案
我不确定我是否理解你的问题到底是关于什么的,但由于我没有足够的声誉来发表评论,我会尽我所能帮助你进行审讯。:)
首先,关于 queries.js 文件,它不完全是 IMO 模型,而是 DAO(数据访问对象)文件。DAO 位于模型(实际上是数据库)和控制器层之间。在您的数据模型中,每个对象(用户、宠物、任何您想要的)通常都有一个 DAO 文件。
当数据模型相当复杂时,使用诸如 Mongoose 之类的对象关系映射 (ORM) 来映射您的数据库并在您的对象上执行复杂的过程会很有用。在这种情况下,您可能需要每个对象都有一个特定的文件,以便描述您的模型并存储您的查询。但是由于您不需要 ORM,您的 DAO 可以直接与您的数据库交互。这就是您没有 User.js 文件的原因。
关于 db 对象的使用方式,我认为您应该直接参考pg-promise 文档。
重要提示:对于任何给定的连接,您应该只在一个单独的模块中创建一个数据库对象,以便在您的应用程序中共享(参见下面的代码示例)。相反,如果您继续动态创建数据库对象,您的应用程序将遭受性能损失,并且将在开发环境中收到警告(当 NODE_ENV = 开发时)
事实上, pg-promise 中的 db 对象代表数据库本身,实际上是为同时使用多个数据库而设计的,目前这似乎不是你的情况。
最后,说到渲染函数,我相信它应该在控制器中,因为你的 DAO 不应该知道它收集的数据将如何使用。从长远来看,模块化始终是一种节省时间的选择。
此外,请注意,您以后可能需要在 DAO 和控制器之间建立一个业务层,以便预处理和后处理您要保留或显示的数据。在这种情况下,例如,如果您需要从数据库中请求数据,则需要 在业务层处理数据后呈现数据。如果渲染是在 DAO 层中进行的,那将是不可能的。
在我之前提供的 pg-promise 的 db 对象连接的链接中,您还可以找到有关该any()
方法的文档。你可能已经查过了。它特别声明它返回
一个代表查询结果的 promise 对象:
当没有返回行时,它会解析为一个空数组。
当返回 1 行或更多行时,它使用行数组解析。
所以你返回的数据是一个 JS 数组。如果你想让它成为一个 JS 对象,只需使用 JSON.stringify(yourArray) 来处理你的数据,然后在你的控制器中渲染它。但我想知道 Pug 是否无法直接使用您的数据。
此外,如果您无法从 DAO 中获取任何数据,也许您应该检查您的data
对象是否为空,因为 any() 方法可以容忍这种情况。如果您希望您的查询总是返回一些东西,您可能需要考虑使用many()
或one()
方法。
我希望这可以帮助你。
推荐阅读
- javascript - 流类型在看似不相关的类型上抛出错误
- python - 从 StreamReader 读取,同时也接收事件 python asnycio
- java - 为所有用户在 Ubuntu 16 上安装 OpenJDK 9
- javascript - TypeError:无法在“CanvasRenderingContext2D”上执行“drawImage”:提供的值不是类型“(CSSImageValue 或 HTMLImageElement
- kdb - kdb 项目被列出并转换为行
- c++ - c++ rand() 仅在 1-10 之间生成 8
- jquery - Uncaught SyntaxError: Unexpected token: 当试图解析 JSON 请求时
- ruby-on-rails - Rails - 从集合中获取多态子项作为 ActiveRecord::Relation
- r - 带有网格的地图中的线交叉(ggplot)
- android - android更快的截屏方式?