连接/断开连接到数据库的最佳做法是什么?

时间:2021-06-04 20:07:17

I'd like to know how to work with connectivity to a database in MEAN stack application. In particular, when should I create a connection to a database and when should I destroy a connection to a database. Should I create and destroy a connection on every new HTTP request or should I store a once created connection and use it for any subsequent requests as long as possible. I use Mongoose as a modeling tool.

我想知道如何使用MEAN堆栈应用程序中的数据库连接。特别是,何时应该创建与数据库的连接,何时应该销毁与数据库的连接。我应该在每个新的HTTP请求上创建和销毁连接,还是应该存储一次创建的连接,并尽可能长时间地将其用于任何后续请求。我使用Mongoose作为建模工具。

Here is an example. This is my routes.js file with a route /index. A request to this route should fetch some date from MongoDb database. It bothers me how I connect and disconnect to a database now. Yes, I connect and disconnect to a database exactly as written in Mongoose docs, but it it the right way to do it in a serious production environment?

这是一个例子。这是我的routes.js文件,带有路由/索引。对此路由的请求应从MongoDb数据库中获取一些日期。困扰我现在如何连接和断开数据库。是的,我完全按照Mongoose docs中的说法连接和断开数据库,但它是在严肃的生产环境中进行的正确方法吗?

var express = require('express');
var router = express.Router();

var config = require('./db-config');

// I create a Mongoose instance as a module object,
// as opposite to create it in every request handler function below.
var mongoose = require('mongoose');

var productSchema = require('../db/productSchema'); // model schema is also a module-wide object

// And here is a request handler function.
// It is called on every request as a brand new.
// I create and destroy a database connection inside this request handler
router.get('/index', function(req, res, next) {

    // I connect to a database on every request.
    // Do I need to do it here in a request handler?
    // May I do it outside of this request handler on a module-wide level?
    mongoose.connect('mongodb://my_database');

    // I create a new connection here in a request handler.
    // So it lives only during this request handler run.
    // Is this the right way? May I do it outside of this request handler 
    // on a module-wide level and somehow keep this connection and use it 
    // in every subsequent requests to this or any other route in the app?
    var db = mongoose.connection;

    db.on('connecting', function() {
        console.log('connecting');
    });

    db.on('connected', function() {
        console.log('connected');
    });

    db.on('open', function() {
        console.log('open');
    });

    db.on('error', console.error.bind(console, 'connection error'));

    db.once('open', function(cb) {
        var Product = mongoose.model('Product', productSchema);
        Product.find({category: "books"}, function(err, prods) {
            if (err) return console.error(err);

            // I close a connection here in a callback. 
            // As soon as successfully fetched the data. 
            // Do I need to close it after every request? 
            // What is the right place and time to do it? 
            db.close(disconnect);
            res.json(prods);
        });
    });
})

Found some good answers:

找到了一些好的答案:

https://softwareengineering.stackexchange.com/questions/142065/creating-database-connections-do-it-once-or-for-each-query

What are best practices on managing database connections in .NET?

在.NET中管理数据库连接的最佳实践是什么?

4 个解决方案

#1


14  

Its best practice to have your db connection in a separate module (db.js)

将数据库连接放在单独的模块中的最佳实践(db.js)

var mongoose = require('mongoose')

mongoose.connect('mongodb://localhost/dbname', function(){
    console.log('mongodb connected')
})
module.exports = mongoose

Each model should have a separate module that takes in the db connection (post.js)

每个模型应该有一个单独的模块,它接受数据库连接(post.js)

var db = require('../db.js')
var Post = db.model('Post', {
    username: {type: String, required: true},
    body: {type: String, required: true},
    date: { type: Date, required: true, default: Date.now }  
})

module.exports = Post

Then whenever you need to use that data set just require it and make calls

然后,只要您需要使用该数据集,只需要它并进行调用

var Post = require('/models/post')
Post.save()
Post.find()

#2


2  

This is an opinion based question I'd say. What I use for my app is

这是一个基于意见的问题我会说。我用于我的应用程序的是

app.get('/', function (req, res) {
res.sendfile('index.html');
});
mongoose.connect('mongodb://localhost:27017/my_db'); 

This way I create a connection once rather than on every HTTP request. Your way should work fine but it seems you will have to connect and disconnect the db to your app way too many times specially when the app is in development.

这样我就可以创建一次连接而不是每个HTTP请求。你的方式应该工作正常,但似乎你必须连接和断开数据库与你的应用程序方式太多次特别是当应用程序在开发中。

#3


2  

You want your connection to act like a singleton so as mentioned in the answer above it makes sense to do it outside of, and preferable before your routes:

你希望你的连接像单身一样行动,正如上面的答案所提到的那样,在你的路线之外做这件事是有道理的,并且更可取:

var compression = require('compression');
var express  = require('express');
var app      = express();
var port     = process.env.PORT || 8080;
var cookieParser = require('cookie-parser');
var bodyParser   = require('body-parser');
var session      = require('express-session');
...

app.use(compression());
// db
var mongoose = require('mongoose');
var configDB = require('./config/database.js');
mongoose.connect(configDB.url); // connect to our database

config/database.js:

module.exports = {
'url' : '@localhost:27017/dbname'
};

#4


0  

This is my solution :

这是我的解决方案:

import express from 'express';
import mongoose from 'mongoose';
import { name } from '../package.json';
import * as localconfig from './local-config';
import debug from 'debug';
debug(name);
const app = express();

const port = process.env.PORT || 3000;
const mongoUrl = localconfig.credentials.MONGO_URL;

import usersRoutes from './routes/users/user-routes';

app.use('/v1/users', usersRoutes);

mongoose.connect(mongoUrl)
    .then(() => {
        debug('DB connection successful');
        app.listen(port, '0.0.0.0', () => {
            debug(`Running on port ${port}`);
        });
    })
    .catch((err) => {
        debug(err);
    });

You should first check weather the connection is successful or not and only then listen to a certain port. This is my app.js file where all the routes are loaded, so you do not have to call the db connection in all your files. You have a single config file where all the config is done. Your router file user-routes.js will look something similar to this:

您应首先检查天气连接是否成功,然后才能收听某个端口。这是我的app.js文件,其中加载了所有路由,因此您不必在所有文件中调用db连接。您有一个配置文件,其中所有配置都已完成。您的路由器文件user-routes.js看起来与此类似:

import express from 'express';

import User from '../models/user'
const router = express.Router();

router.get('/', (req, res, next) => {
    User.find()
        .then((response) => res.json(response))
        .catch((err) => next(err));
});

module.exports = router;

#1


14  

Its best practice to have your db connection in a separate module (db.js)

将数据库连接放在单独的模块中的最佳实践(db.js)

var mongoose = require('mongoose')

mongoose.connect('mongodb://localhost/dbname', function(){
    console.log('mongodb connected')
})
module.exports = mongoose

Each model should have a separate module that takes in the db connection (post.js)

每个模型应该有一个单独的模块,它接受数据库连接(post.js)

var db = require('../db.js')
var Post = db.model('Post', {
    username: {type: String, required: true},
    body: {type: String, required: true},
    date: { type: Date, required: true, default: Date.now }  
})

module.exports = Post

Then whenever you need to use that data set just require it and make calls

然后,只要您需要使用该数据集,只需要它并进行调用

var Post = require('/models/post')
Post.save()
Post.find()

#2


2  

This is an opinion based question I'd say. What I use for my app is

这是一个基于意见的问题我会说。我用于我的应用程序的是

app.get('/', function (req, res) {
res.sendfile('index.html');
});
mongoose.connect('mongodb://localhost:27017/my_db'); 

This way I create a connection once rather than on every HTTP request. Your way should work fine but it seems you will have to connect and disconnect the db to your app way too many times specially when the app is in development.

这样我就可以创建一次连接而不是每个HTTP请求。你的方式应该工作正常,但似乎你必须连接和断开数据库与你的应用程序方式太多次特别是当应用程序在开发中。

#3


2  

You want your connection to act like a singleton so as mentioned in the answer above it makes sense to do it outside of, and preferable before your routes:

你希望你的连接像单身一样行动,正如上面的答案所提到的那样,在你的路线之外做这件事是有道理的,并且更可取:

var compression = require('compression');
var express  = require('express');
var app      = express();
var port     = process.env.PORT || 8080;
var cookieParser = require('cookie-parser');
var bodyParser   = require('body-parser');
var session      = require('express-session');
...

app.use(compression());
// db
var mongoose = require('mongoose');
var configDB = require('./config/database.js');
mongoose.connect(configDB.url); // connect to our database

config/database.js:

module.exports = {
'url' : '@localhost:27017/dbname'
};

#4


0  

This is my solution :

这是我的解决方案:

import express from 'express';
import mongoose from 'mongoose';
import { name } from '../package.json';
import * as localconfig from './local-config';
import debug from 'debug';
debug(name);
const app = express();

const port = process.env.PORT || 3000;
const mongoUrl = localconfig.credentials.MONGO_URL;

import usersRoutes from './routes/users/user-routes';

app.use('/v1/users', usersRoutes);

mongoose.connect(mongoUrl)
    .then(() => {
        debug('DB connection successful');
        app.listen(port, '0.0.0.0', () => {
            debug(`Running on port ${port}`);
        });
    })
    .catch((err) => {
        debug(err);
    });

You should first check weather the connection is successful or not and only then listen to a certain port. This is my app.js file where all the routes are loaded, so you do not have to call the db connection in all your files. You have a single config file where all the config is done. Your router file user-routes.js will look something similar to this:

您应首先检查天气连接是否成功,然后才能收听某个端口。这是我的app.js文件,其中加载了所有路由,因此您不必在所有文件中调用db连接。您有一个配置文件,其中所有配置都已完成。您的路由器文件user-routes.js看起来与此类似:

import express from 'express';

import User from '../models/user'
const router = express.Router();

router.get('/', (req, res, next) => {
    User.find()
        .then((response) => res.json(response))
        .catch((err) => next(err));
});

module.exports = router;