sql >> Databasteknik >  >> RDS >> Sqlserver

Hur kan jag använda en enda mssql-anslutningspool över flera rutter i en Express 4-webbapplikation?

Det har gått 3 år sedan jag frågade och svarade på frågan. Sedan dess har några saker förändrats. Här är den nya lösningen baserad på ES6, mssql 4 och Express 4 som jag skulle föreslå idag.

Två nyckelelement spelar här.

  1. Moduler cachelagras efter första gången de laddas. Detta innebär att varje anrop till require('./db') kommer att returnera exakt samma objekt. Det första kravet på db.js kommer att köra den filen och skapa löftet och exportera det. Det andra kravet på db.js kommer att returnera DET samma löfte utan att köra filen. Och det är det löftet som kommer att lösa sig med poolen.
  2. Ett löfte kan sedan bekräftas igen. Och om det löste sig tidigare, kommer det omedelbart att lösas igen med vad det än löste med första gången, vilket är poolen.

I 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}`)
})

I 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
}

I routes/set1.js och 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

För att sammanfatta

Du kommer alltid att få samma löfte på grund av modulcaching och det löftet kommer, om och om igen, att lösas med poolen som det löste med första gången. Således använder varje routerfil samma pool.

BTW:det finns enklare sätt att gå om försöksfångsten på expressrutten som jag inte kommer att ta upp i det här svaret. Läs om det här:https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016

Den gamla lösningen

Det här är lösningen jag postade för 3 år sedan, eftersom jag trodde att jag hade ett svar som var värt att dela och jag kunde inte hitta en dokumenterad lösning någon annanstans. Även i några nummer (#118, #164, #165) på node-mssql diskuteras detta ämne.

I 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);
});

I 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;
};


  1. Implementera Secure Multicloud MySQL-replikering på AWS och GCP med VPN

  2. Kardinalitetsuppskattning för flera predikat

  3. PostgreSQL långsam på ett stort bord med arrayer och massor av uppdateringar

  4. Skapa tabell (struktur) från befintlig tabell