繁体   English   中英

使用 NodeJS 从 MySQL 查询

[英]Querying From MySQL Using NodeJS

我正在尝试查询 MySQL 数据库表。 我使用 NodeJS / Express 作为我的后端。

我已经像这样设置了 MySQL ..(是的,我检查了后端是否连接到数据库。我刚刚遗漏了下面的凭据。)

const db = mysql.createConnection({
  host: '',
  user: '',
  password: '',
  database: ''
});

db.connect((error) => {
  if (error) {
    console.log(error);
  } else {
    console.log("MySQL connected.");
  }
});

我试图让我的代码井井有条,所以我在配置文件中有这个。 我想导出 db 常量并从其他文件中执行 db.query() 。

因此,我做到了这一点。

module.exports = {
  app: app,
  db: db
};

但是,当我在其他文件中需要 db 时,请执行以下操作

const db = require('../../server');

它说 db.query 不是 function。 有谁知道为什么会这样说? 我似乎无法正确导出它。

谢谢。

在我的应用程序中,我以这种方式使用它:

const mysql = require('mysql');

connection = mysql.createPool({
    host: '***',
    user: '***',
    password: '***',
    database: '***'

});

module.exports = connection;

我需要在哪里称呼它:

const conn = require('path/to/dbfile.js');

然后只需使用:

conn.query('SELECT * FROM TEST', function (err, rows) {
    if (err)
        return err;
    return rows;
});

简短的回答

你可能有一个循环依赖,即你有一个文件a require s 文件b ,但文件brequire s 文件a 结合使用module.exports = something (而不是修改现有的exports对象),这会导致其中一个模块将从require另一个模块返回一个空的 object (它的导出似乎不存在那里) )。

快速修复最有可能将module.exports = { app, db }替换为 exports.app = exports.app = app; exports.db = db export.db exports.app = app; exports.db = dbObject.assign(exports, { app, db })

至于为什么,以及如果这不是最佳解决方案存在哪些其他选项,请阅读下文。

长答案

听起来好像你有一个循环依赖问题。

让我解释一下,请耐心等待,我们最终会解决您的问题。

看,每个模块都以一个空的 object 作为module.exports (也可以作为exports使用)。 如果您仅通过执行 exports.something exports.something = something (或module.exports.something = something修改此 object,那么即使在顶层存在循环依赖关系,只要导出 object 的属性为稍后才访问。 例如:

/* a.js */
const b = require('./b')

exports.getX = function () {
  return b.getY() * 2
}

exports.getZ = function () {
  return 5
}
/* b.js */
const a = require('./a')

exports.getY = function () {
  return a.getZ() * 3
}
/* main.js */
const a = require('./a')

console.log(a.getX()) // Returns 30

这里我们有一个循环依赖( a依赖于b ,但b也依赖于a )。 然而,它有效。

上面的代码之所以有效,是因为在评估a.js时,它的exports object 将已经存在,然后当它需要b.js并且b.js再次需要a.js时,即使a.js甚至还没有完成运行它的顶部级代码, b.js中的a变量已经可以分配到 a.js 的exports a.js 那时它是一个空的 object,但是当行return a.getZ() * 3运行时,object 将设置属性getZ

  1. main需要a
  2. a需要b
  3. b需要a并获取当前为空的 object
  4. b在其导出和返回上定义getY
  5. a在其导出上定义getXgetZ (与b已经得到引用的 object 完全相同!)并返回
  6. main调用a.getX()
  7. a.getX调用b.getY
  8. b.getY现在只访问现在确实存在的a的属性getZ (它是在步骤 5 中设置的)。

请注意,如果我们编写了const { getZ } = require('./a')则它不会起作用,因为那时getZ属性将在步骤 3 中被访问,而它还不存在。

但是,类似地,如果我们像这样编写a.js ,它也会停止工作:

const b = require('./b')

function getX () {
  return b.getY() * 2
}

function getZ () {
  return 5
}

module.exports = { getX, getZ }

The big difference here is that we are now reassigning the exports object , So, the object that b gets at step 3 is the original (empty) object, but we are then reassigning it to a new object (instead of modifying the existing object) ,并且b中的代码永远没有机会获得对该 object 的引用,然后:您遇到这种情况:A require给您一个空的 object,并且尝试调用a.getZ将失败, a.getZ is not a function (因为它是undefined )。

(顺便说一下, module.exports = somethingexports = something不同,因为后者重新分配了本地exports变量,并且不会改变其他模块将看到的导出内容!)

我现在的假设是您在这里遇到了类似的问题 - 执行数据库连接的文件需要使用数据库连接的文件,但反过来也是如此。

您现在有两个选择:

  • module.exports = { app, db }替换为 exports.app = exports.app = app; exports.db = db export.db exports.app = app; exports.db = dbObject.assign(exports, { app, db }) - 两者都会改变现有的导出 object 而不是替换它。
  • 稍后需要其中一个文件,或者通过在另一个 function 中需要它,或者通过创建一个占位符变量let otherModule并导出一个使用otherModule = require('./otherModule')实际填充它的init方法,然后在 require 之后的第二步调用这个init方法,从而将模块代码的评估和它的依赖项的 require 解耦,打破循环依赖。

第一个选项可能是解决问题的最简单、最直接的方法。 但是,我不知道您的代码的 rest,因此可能还有其他障碍阻碍了此解决方案的可行性。

所以,让我详细解释第二个选项,因为它也可以经常解决问题。

第二个选项的示例:

/* a.js */
let b

function getX () {
  return b.getY() * 2
}

function getZ () {
  return 5
}

function init () {
  b = require('./b')
}

module.exports = { init, getX, getZ }
/* b.js */
const a = require('./a')

function getY = function () {
  return a.getZ() * 3
}

module.exports = { getY }
/* main.js */
const a = require('./a')
a.init()

console.log(a.getX()) // Returns 30

即使重新分配module.exports ,此代码现在也可以工作,因为现在事情以不同的顺序发生:

  1. main需要a
  2. a将其导出 object 替换为包含initgetXgetZ并返回的导出 [请注意,这部分代码之前运行得更晚]
  3. main调用a.init()
  4. a.init需要b
  5. b需要a并使用所有方法获取其最终导出 object [请注意,以前它得到一个尚未填充的 object 因为a还没有完全加载!]
  6. b将其导出 object 替换为包含getY并返回
  7. a.init返回
  8. main调用a.getX()
  9. 从现在开始一切正常,因为ab现在都已经引用了彼此的完全填充的导出对象

实现第二个选项“稍后要求”的另一种方法是在已使用的导出 function 中require另一个模块,但这可能有其缺点(例如,如果在许多情况下需要重复代码函数,并且执行速度稍慢,因为require一遍又一遍地调用)。 在我们的示例中,这意味着这样做:

/* b.js */

function getY () {
  const a = require('./a')
  return a.getZ() * 3
}

module.exports = { getY }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM