sql >> データベース >  >> RDS >> Sqlserver

Express 4 Webアプリケーションの複数のルートで単一のmssql接続プールを使用するにはどうすればよいですか?

    質問して答えてから3年になります。それ以来、いくつかのことが変わりました。これが、今日提案するES6、mssql 4、およびExpress4に基づく新しいソリューションです。

    ここでは2つの重要な要素が働いています。

    1. モジュールは、最初にロードされた後にキャッシュされます。これは、require('./ db')を呼び出すたびに、まったく同じオブジェクトが返されることを意味します。 db.jsの最初のrequireは、そのファイルを実行し、promiseを作成してエクスポートします。 db.jsの2番目のrequireは、ファイルを実行せずに同じpromiseを返します。そして、プールで解決するのはその約束です。
    2. 約束は再び具体化することができます。また、以前に解決した場合は、最初に解決したもの、つまりプールですぐに再解決します。

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

    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
    

    要約する

    モジュールのキャッシュにより、常に同じPromiseが得られ、そのPromiseは、最初に解決したプールで何度も解決されます。したがって、各ルーターファイルは同じプールを使用します。

    ところで:私がこの答えでカバーしない高速ルートでトライキャッチについて行くより簡単な方法があります。ここでそれについて読んでください:https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016

    古いソリューション

    これは私が3年前に投稿した解決策です。共有する価値のある答えがあり、他の場所で文書化された解決策を見つけることができなかったからです。また、node-mssqlのいくつかの問題(#118、#164、#165)で、このトピックについて説明しています。

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

    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. PostgreSQLの日付から世紀を取得する

    2. SQLServerで最も近い日付を検索する

    3. オフライン国際化アプリの作成方法:複数の言語をサポート

    4. PostgreSQLで既存のテーブルに自動インクリメントの主キーを追加するにはどうすればよいですか?