javascript - 在整个快速应用程序中实现单个数据库池的正确方法
问题描述
注意:这个问题主要是关于节点中的单例对象而不是数据库池
我正在使用 mysqljs 节点模块构建一个 expressjs 应用程序以进行数据库连接。我想创建一个可以在整个应用程序中重复使用的池对象(对于不同的模型等)。我想知道在整个快速应用程序中使用单个对象实例的正确方法是什么
我见过很多例子,人们像这样创建 db.js 文件或 pool.js 文件并在需要的地方使用它
// db.js
var mysql = require('mysql');
var pool;
module.exports = {
getPool: function () {
if (pool) return pool;
pool = mysql.createPool(dbConfig);
return pool;
}
};
// app.js
var pool = require('pool').getPool();
pool.query('SELECT * FROM users');
但是我觉得这仍然不是正确的方法,因为您每次需要对象时都依赖 nodejs 缓存返回相同的实例。如果节点最终加载了两次代码,你最终会得到两个池,例如
const poolA = require('./pool').getPool();
const poolB = require('./POOL').getPool(); // resolves to same file but node will not get result from cache
console.log(poolA === poolB); // false
从我读过的大部分内容来看,由于这种行为,通常不建议在节点应用程序中使用单例对象,但这似乎是快速应用程序的常见用例。所以我想知道人们是如何在他们的应用程序的生命周期内创建他们的单一池的?
注意:我目前所做的是在应用程序根目录中实例化池,然后将实例作为构造函数参数传递,但我也不喜欢这个
解决方案
简短的回答
我在您的代码中没有看到任何问题。
长答案
此解决方案假设您实际上没有POOL.js
使用相同确切代码命名的文件。
下面解析到与您使用启用的文件系统require
相同的文件。例如或。pool.js
case-insensitivity
NTFS
APFS
const poolB = require('./POOL').getPool();
如果你使用case sensitive
这样的文件系统,ext4
你会得到错误。
Error: Cannot find module './POOL'
node
根据您提供的文件路径名在内部缓存文件。从来源:
const relativeResolveCache = Object.create(null);
relResolveCacheIdentifier = `${parent.path}\x00${request}`;
const filename = relativeResolveCache[relResolveCacheIdentifier];
if (filename !== undefined)
...
因为JavaScript
is ,一个具有属性(简化)case-sensitive
的对象(来自上面的, )并且将是不同的并且完全引用 2 个不同的对象引用。cache
pool
POOL
结论
注意带有文件名或标识符名称的陷阱。
推荐阅读
- circleci - CircleCI:跳过整个工作流程
- python - 有没有办法在 python 中使用 gspread 复制工作表?
- wordpress - 我在哪里可以修改 woocomerce 显示产品附加信息的方式?
- c++ - MSVC 预处理器错误 - 在参数计数上重载 C/C++ 宏
- javafx - 在 SceneBuilder 中将 TilePane 的高度和宽度拟合到父 ScrollPane 的问题
- c# - 当我在 TabbedPage ViewModels 中使用 PopAsync 时,它不起作用
- c# - cicle if-do 虽然不工作,但看起来很完美
- azure - 是否有 PowerShell cmdlet 来获取引用 Azure Active Directory 中域名的资源?
- kotlin - Kotlin 对“假定”正确类型的类型推断
- php - 验证输入是十进制数 - 货币汇率的输入字段