2016-10-07 8 views
0

PS:質問は長くなるかもしれませんが、以下に焦点が絞られた質問があります。正しい方法でExpressJs + MySQLを使用する方法

私は、それが理にかなっているために、明示的にMySQLを使用しなければならない不幸な人の中にいます。これはAPIバックエンドとして使用されます。自分のサイトにあるジェネレータ(https://expressjs.com/en/starter/generator.html)を使ってエクスプレスアプリを生成し、mysqljs(https://github.com/mysqljs/mysql)からmysqlをインストールしました。

ここでは、expressの例はすべてMongoDbを例にしており、ラッパーを使用しています。そして、mysqljsの例ではあまり説明しません。だから私のプロジェクトの構造はいくつかの特定の質問です。

bin - auto generated files to start the app 
config 
models (Maybe have a base model which can talk to db wrapper and other models can extend that) 
routes 
.... index.js 
.... users.js etc etc (each included in the app.js to have some sort of structure) 
utils 
.... db.js (check code below) 
app.js 
package.json 

今これは私が私のdb.js

var mysql = require('mysql'); 

var pool = mysql.createPool({ 
    connectionLimit : 100, 
    host: 'localhost', 
    user: 'root', 
    password: 'notsoblank', 
    database: 'somedevdb' 
}); 

module.exports = pool; 

そして(users.js、index.jsなど)私のルートファイルで、私はこれを使用しています中に持っているものです。

var express = require('express'); 
var router = express.Router(); 
var db = require('../utils/db'); 
/* GET groups listing. */ 
router.get('/', function(req, res, next) { 
    db.getConnection(function(err, connection) { 
     var sql = 'SELECT * from groups'; 
     connection.query(sql, function(err, rows, fields) { 
      if (err) throw err; 
      res.json(rows); 
     }); 
     connection.release(); 
    }); 
}); 

module.exports = router; 

そしてapp.jsでは、これ以上のファイルは次のように含まれています:

var express = require('express'); 
var path = require('path'); 
var logger = require('morgan'); 

var app = express(); 

var routes = require('./routes/index'); 
var users = require('./routes/users'); 
var groups = require('./routes/groups'); 

app.use('/apis/groups', groups); 

module.exports = app; 

このアプリを実行している場合は、localhost:5000\apis\groupsのようなAPIエンドポイントがあり、これは他のアプリで使用できます。ここで

はこれに基づいて、私の質問です:

  1. 私はすべてのルート・ファイル内のdb.js(index.js、users.js、groups.js)ことをインポートしています。これは、我々がAPIをヒットする度に作成されるDBプールがあることを意味しますか?

  2. 私は自分の仕事のために多くのプレーンなSQLを書くつもりです。今ではアダプタやOEMがたくさんあることを知っていますが、getOneやaddやdeleteなどのメソッドを使って簡単なラッパーを作成したいだけです。そのための最良の方法は何でしょうか。

  3. Connection.queryは約束を返します。さらなる操作をしたい場合は、これを実行する最良の方法は何ですか。

db.jsにdb資格情報を保持すること以外に、このアプローチに間違いがありスケーリングを妨げる可能性があります。

+0

誰もそれを使用していなかった場合、および/またはそれが駄目な解決策だった場合、あなたは残念です。これはそうではありません。私は、https://codeforgeek.com/2015/01/nodejs-mysql-tutorial/ – Amnon

+0

のような多くのチュートリアルの1つを歩くことをお勧めします。これはそれを組み込み、開始するための基本的な例です。誰もあなたが始まった後に何をすべきかを教えてくれません。私はすでに接続プールを作成してクエリを作成することができますが、コードの重複が多く見られ、全体的に見た目が乱雑です。時には私は何が起こっているのかわからないことがあります。 –

+0

sequelizeや別のORMを使用すると、コードのメンテナンスに長期間役立つことがあります。 – Paul

答えて

0

コードの膨らみを減らすのに役立つ何らかのdbヘルパーモジュールを探しているのですが(これはORMを介して解決された問題だと思いますが)、それはかなり簡単です。あなたが望む機能を何でも公開し、反復的なものを隠すだけです。このような何かが動作します:あなたの元に間違っ

var db = require('./db')(myOptions); 

db.query('select * from groups', console.log); 

カップルの事:

// db.jsいうだけでプールにさらすよりも、その後のような何かをするだろうコードを呼び出す

var mysql = require('mysql'); 

// expose the options so that the calling code can inject the password and so on, probably from config or process.env variables. 
function db(options){ 
    // todo: sanitize options and set defaults 
    var pool = mysql.createPool(options); 

    return { 
    query : function(sql, callback){ 
     db.getConnection(function(err, connection) { 
     connection.query(sql, function(err, rows, fields) { 
      callback(err, rows, fields); 
      connection.release(); 
     }); 
     }); 
    } 

    } 

} 


module.exports = db; 

コード。

1)接続していました。接続を取得するためのコールバックでrelease()を呼び出し、クエリを返しません。遅いDBクエリでは、接続の使用を終了する前に接続を解放する可能性があります。

2)Promisesを使用している場合を除いて、コールバックにエラーを「スロー」しないでください。何らかの方法で処理したり、次のコールバックに渡したりする必要があります。

+0

私はこのファイルが必要な場合、私のルートのすべてを言いますが、それぞれに別々のプールが作成されますか?私のdbが一度に10の接続を処理できるならば、接続の総数を最大10に保ちたいと思うので、扱いにくいでしょう。各ルートが独自の接続を10つ作成する場合、遅延していても、単純に違う。 –

+0

このデータベースのインスタンスを1つだけ作成し、すべてのルートでこれを使用する必要があると思えば、正しい軌道に乗っていますか? –

+0

私はそれを書きました。はい、エクスポートされた関数を呼び出すたびにプールが作成されます。あなたは必要ではなくシングルトンのメカニクスを使うことができます。そうしないと、db.js本体のconfigからオプションを取得し、関数の外にあるプールをインスタンス化します。 – Paul

関連する問題