我有一个像这样的路由器文件:
import express from 'express';
import health from './health';
import surface from './surface';
const router = express.Router();
router.use('/health', health);
router.use('/surface', surface);
router.get('*', (req, res) => {
res.status(404);
res.json({
message: 'Uknown API endpoint'
});
});
export default router;
在每个路由中,我使用NPM mysql
包创建连接,然后在我调用res.send()
之前结束它。 IIRC创建连接并按查询结束它将是一个坏主意。
我尝试过做中间件:
router.use((req, res, next) => {
next();
mySingletonWrappingMysql.connection.end();
});
鉴于我的路由正在执行异步操作,endConnection
调用过早发生。 next
并不是真正的异步,所以我不能await next
,我甚至不确定这是否是正确的方法/地方。此示例使用单例,因为我也不确定如何正确设置要在路径中使用的新实例。 req.param
似乎是一个不是最佳原因的选项,似乎是特殊查询参数变种。
答案 0 :(得分:5)
您需要连接到MySQL的连接池。这是一个可串行重用的连接资源池。你需要的时候拿一个,当你完成时就把它拿走。因此,每个请求,甚至每个中间件调用,都可以使用连接而不必担心并发(这对连接不起作用)。看到这个。 https://www.npmjs.com/package/mysql#pooling-connections
像这样设置你的游泳池,只需一次。每个node.js服务器实例都需要一个池,用于它使用的每个单独的MySQL服务器。
var mysql = require('mysql');
var pool = mysql.createPool({
connectionLimit : 10,
host : 'example.org',
user : 'bob',
password : 'secret',
database : 'my_db'
});
此createPool操作创建一个最多包含十个连接的池。每次使用池时,它都会检查其所有连接是否都很忙。如果没有,它会让你空闲使用。如果他们都忙,它会打开一个新的。但是,如果池中已经有connectionLimit
个连接,它将等待一个空闲。
然后随意的一次性查询就像这样工作。在REST服务器中,您可能会发现对数据库的单个查询可以满足某些GET查询。这些都非常简单。没有必要明确地从池中获取或释放连接。并且,当您释放连接时,它将保持与DBMS的连接,以备将来的请求使用。如果满足特定请求需要两个或三个SELECT查询,您也可以使用此技术。但是,每个查询可能使用池中的不同连接。
pool.query('SELECT whatever FROM whatever',
function (error, results, fields) {
if (error) throw error;
/* handle your results array */
})
如果您需要为多个查询获取连接,那么它几乎一样简单,但您需要在完成后记住release()
连接。当您的某些查询依赖于序列中先前查询的结果时,您需要执行此操作。
pool.getConnection(function(err, connection) {
if (error) throw error;
connection.query('INSERT INTO sometable ...',
function (error, results, fields) {
if (error) {
connection.release();
throw error;
}
connection.query('INSERT INTO detail ... (LAST_INSERT_ID()...)',
function (error, results, fields) {
connection.release();
if (error) throw error;
});
});
});
您可能希望使用promises来避免函数嵌套,特别是如果您想运行一系列查询。