Прошло 3 года с тех пор, как я задал вопрос и ответил на него. С тех пор кое-что изменилось. Вот новое решение на основе ES6, mssql 4 и Express 4, которое я бы предложил сегодня.
Здесь играют роль два ключевых элемента.
- Модули кэшируются после первой загрузки. Это означает, что каждый вызов require ('./ db') будет возвращать один и тот же объект. Первое требование db.js запустит этот файл, создаст обещание и экспортирует его. Второе требование db.js вернет ТО же самое обещание без запуска файла. И это обещание разрешится с пулом.
- Обещание можно снова сформулировать. И если он разрешился раньше, он немедленно разрешится снова с тем, что было разрешено в первый раз, то есть пулом.
In server.js
const express = require('express')
// require route handlers.
// they will all include the same connection pool
const set1Router = require('./routes/set1')
const set2Router = require('./routes/set2')
// generic express stuff
const app = express()
// ...
app.use('/set1', set1Router)
app.use('/set2', set2Router)
// No need to connect the pool
// Just start the web server
const server = app.listen(process.env.PORT || 3000, () => {
const host = server.address().address
const port = server.address().port
console.log(`Example app listening at http://${host}:${port}`)
})
In db.js
const sql = require('mssql')
const config = {/*...*/}
const poolPromise = new sql.ConnectionPool(config)
.connect()
.then(pool => {
console.log('Connected to MSSQL')
return pool
})
.catch(err => console.log('Database Connection Failed! Bad Config: ', err))
module.exports = {
sql, poolPromise
}
В routes/set1.js
и routes/set2.js
const express = require('express')
const router = express.Router()
const { poolPromise } = require('./db')
router.get('/', async (req, res) => {
try {
const pool = await poolPromise
const result = await pool.request()
.input('input_parameter', sql.Int, req.query.input_parameter)
.query('select * from mytable where id = @input_parameter')
res.json(result.recordset)
} catch (err) {
res.status(500)
res.send(err.message)
}
})
module.exports = router
Подведем итоги
Вы всегда будете получать одно и то же обещание из-за кэширования модуля, и это обещание будет снова и снова выполняться с пулом, с которым оно было разрешено в первый раз. Таким образом, каждый файл маршрутизатора использует один и тот же пул.
Кстати: есть более простые способы попробовать поймать на экспресс-маршруте, о которых я не буду рассказывать в этом ответе. Прочтите об этом здесь: https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016.
Старое решение
Это решение, которое я опубликовал 3 года назад, потому что я считал, что у меня есть ответ, которым стоит поделиться, и я не мог найти документированное решение в другом месте. Также в нескольких вопросах (# 118, # 164, # 165) на узле-mssql обсуждается эта тема.
In server.js
var express = require('express');
var sql = require('mssql');
var config = {/*...*/};
//instantiate a connection pool
var cp = new sql.Connection(config); //cp = connection pool
//require route handlers and use the same connection pool everywhere
var set1 = require('./routes/set1')(cp);
var set2 = require('./routes/set2')(cp);
//generic express stuff
var app = express();
//...
app.get('/path1', set1.get);
app.get('/path2', set2.get);
//connect the pool and start the web server when done
cp.connect().then(function() {
console.log('Connection pool open for duty');
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
}).catch(function(err) {
console.error('Error creating connection pool', err);
});
In routes/set1.js
var sql = require('mssql');
module.exports = function(cp) {
var me = {
get: function(req, res, next) {
var request = new sql.Request(cp);
request.query('select * from test', function(err, recordset) {
if (err) {
console.error(err);
res.status(500).send(err.message);
return;
}
res.status(200).json(recordset);
});
}
};
return me;
};
person
Christiaan Westerbeek
schedule
20.05.2015