首页 > 解决方案 > 使用 pug、Postgres 和适当的 MVC 表达

问题描述

我最近开始使用 Node.js + Express.js(用 pug 生成)+ pg-promise 来处理数据库。

我的第一个目标是从 Postgres(已经设置)获取数据并使用 render 和 pug 漂亮地显示它。假设它是用户表中的用户列表。

这个宁静的教程中,我学习了如何获取数据并将其以 JSON 格式返回 -它有效

根据Mozilla 的教程,我分离了我的代码:

    // 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() 来满足读者。

标签: node.jspostgresqlexpressmodel-view-controllerpg-promise

解决方案


我不确定我是否理解你的问题到底是关于什么的,但由于我没有足够的声誉来发表评论,我会尽我所能帮助你进行审讯。:)

首先,关于 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()方法。

我希望这可以帮助你。


推荐阅读