node.js - 用哈巴狗、Postgres 和适当的 MVC 表达

标签 node.js postgresql express model-view-controller pg-promise

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

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

关于 this Restful 教程我已经学会了如何获取数据并将其作为 JSON 返回 - 有效

基于 Mozilla's tutorial我分离了我的代码:

  • routes/users.js:我调用 user_controller.user_list 方法的“/”位置(使用 router.get)
  • controllers/userController.js 我导出了 user_list,我想向 model 询问数据并调用 render如果我有结果
  • queries.js 这是我的模型吗?但我不确定。它具有 API:通过 promise 连接到数据库,以及我将在 Controller 中使用的每个查询的一个函数。我相信每个表(或任何逻辑实体)我应该有一个模型文件,但是在哪里存储 pgp 连接? 此文件基于我提到的第一个教程

    // queries.js (connectionString is set properly to my postgres)
    var pgp = require('pg-promise')(options);
    var db = pgp(connectionString);
    function getUsers(req, res, next) {
        db.any('SELECT (user_id, username) FROM public.users ORDER BY user_id ASC LIMIT 1000')
        .then(function (data) {
            res.json({ data: data });
        })
        .catch(function (err) {
            return next(err);
        });    
    }
    module.exports = {
        getUsers: getUsers
    };

我的问题从这里开始,因为大多数教程使用 mongoose,它对模型-数据库-模式非常友好,我拥有的是简单的“SELECT ...”字符串,我传递给 pg-promise 的 any() 函数。 因此我没有像 User 这样的模型类。

userControllers.js 中,我不知道如何调用 getUsers() 来处理它的数据。从 getUsers() 返回 JS 对象会很好。

另外:我应该在哪里调用渲染?在 Controller 中或仅在

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 位于您的模型(实际上是您的数据库)和您的 Controller 层之间。在您的数据模型中,每个对象(用户、宠物,无论您想要什么)通常都有一个 DAO 文件。

当数据模型相当复杂时,使用 Mongoose 等对象关系映射 (ORM) 来映射数据库并在对象上执行复杂的过程会很有用。在这种情况下,您可能需要每个对象一个特定的文件来描述您的模型并存储您的查询。但由于您不需要 ORM,您的 DAO 可以直接与您的数据库交互。这就是您没有 User.js 文件的原因。

关于db对象的使用方式,我觉得你应该直接引用pg-promise documentation on the matter .

IMPORTANT: For any given connection, you should only create a single Database object in a separate module, to be shared in your application (see the code example below). If instead you keep creating the Database object dynamically, your application will suffer from loss in performance, and will be getting a warning in a development environment (when NODE_ENV = development)

事实上,pg-promise 中的 db 对象代表数据库本身,实际上是为同时使用多个数据库而设计的,目前您的情况似乎不是这样。

最后,关于渲染功能,我认为它应该在 Controller 中,因为您的 DAO 不应该知道它收集的数据将如何使用。 从长远来看,模块化始终是一种节省时间的选择。

此外,请注意您稍后可能需要在 DAO 和 Controller 之间有一个业务层,以便预处理和后处理您将要保留或显示的数据。在这种情况下,例如,如果您需要从数据库中请求数据,您将需要在业务层处理数据之后呈现数据。如果渲染是在DAO层做的,那就不行了。

在我之前提供的指向 pg-promise 的数据库对象连接的链接中,您还可以找到有关 any() 方法的文档。您可能已经查过了。 它特别声明它返回

A promise object that represents the query result:

When no rows are returned, it resolves with an empty array.

When 1 or more rows are returned, it resolves with the array of rows.

所以你返回的数据是一个 JS 数组。如果你想让它成为一个 JS 对象,只需使用 JSON.stringify(yourArray) 在您的 Controller 中呈现数据之前处理您的数据。 但我想知道 Pug 是否不能直接使用您的数据。

此外,如果您无法从 DAO 中获取任何数据,也许您应该检查您的 data 对象是否为空,因为 any() 方法可以容忍这种情况。如果您希望查询始终返回某些内容,您可能需要考虑使用 many()one() 方法。

希望对你有帮助

关于node.js - 用哈巴狗、Postgres 和适当的 MVC 表达,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51516674/

相关文章:

node.js - 如何使用 Node 将二进制对象存储在redis中?

mysql - 将 mysql 连接到 postgresql

ruby-on-rails - 使用 Postgresql 数据库创建 Rails 3.1 应用程序 (OSX Lion)

node.js - Mongoose 必须有一个解决方案,仅更新具有值的字段,即使您传递更多字段

mysql - 将日期时间保存到时间戳列中

javascript - Angular Controller - 保存 Node 发送的接收文件

javascript - Mojito - 加载 NodeJS 模块

postgresql - 无法将 varchar(255) 转换为 float

javascript - Express.js CRUD – Chrome 中的 DELETE 后 GET 挂起

mysql - SequelizeConnectionRefusedError : connect ECONNREFUSED 127. 0.0.1:3306