许多人问:在Nodejs中如何共享Mongoose创建一个数据库链接,而后在此应用程序其它地方都使用这个数据库链接?node
许多国外的帖子对此进行了讨论,可是国内相对沉闷,技术的流行程度和对技术的热衷度也可见一斑。mongodb
Anyway....回到主题数据库
下面这个例子告诉你们如何实现创建一个数据库链接以后在程序的其它地方都使用它。express
例子基于Express, 按照如下步骤生成Express的目录结构并安装必要的包npm
1. npm install -g express-generator浏览器
2. md mytest && cd mytest (创建一个目录,并进入目录)app
3. express -e (生成网站的目录结构,-e 表示用ejs 做为模板,默认模板是jade)mongoose
4. npm install -d (安装依赖项)编辑器
5. npm install mongoose测试
基于Express作这个例子的缘由是我想用Express中的路由,仅此而已
顺便提一句,你们都用什么编辑器写Nodejs代码?我用Sublime Text 2, 很好用。
在这个例子里,咱们往数据库中插入新公司(company集合)和新国家(country集合)咱们会创建一个Mongoose的数据库链接,而后在任何地方都用它。
咱们把代码用文件夹归类,首先在mytest目录下建util目录,在util目录下建schema目录和dal目录,schema目录用来存放定义的schema,dal目录用来存放最终写数据库的代码
建好以后的目录结构以下图:
而后在dal目录下建db.js文件,在db.js中会创建到数据库的链接,代码以下:
var mongoose=require('mongoose'); console.log('Creating global mongoose connection...'); // Build the connection string var dbURI = 'mongodb://localhost:27017/mytest'; // Create the database connection mongoose.connect(dbURI); // CONNECTION EVENTS // When successfully connected mongoose.connection.on('connected', function () { console.log('Mongoose default connection open to ' + dbURI); }); // If the connection throws an error mongoose.connection.on('error',function (err) { console.log('Mongoose default connection error: ' + err); }); // When the connection is disconnected mongoose.connection.on('disconnected', function () { console.log('Mongoose default connection disconnected'); }); // If the Node process ends, close the Mongoose connection process.on('SIGINT', function() { mongoose.connection.close(function () { console.log('Mongoose default connection disconnected through app termination'); process.exit(0); }); }); module.exports=mongoose;
注意最后一句,这里将mongoose对象做为此模块的输出,以便在其它地方使用它。
下面咱们来定义schema,这里就会用到db.js。
先定义company的schema,代码以下:
var mongoose=require('../dal/db.js'); var Schema=mongoose.Schema; var companySchema=new Schema({ Name:String }); module.exports=mongoose.model('Company',companySchema);
而后定义country的schema,代码以下:
var mongoose=require('../dal/db.js'); var Schema=mongoose.Schema; var countrySchema=new Schema({ Name:String }); module.exports=mongoose.model('Country',countrySchema);
注意,以上两个模块的输出是model对象。
如今来写插入数据库的代码。
在dal文件夹中,新建companyDAL.js文件,代码以下:
var Company=require('../schema/company.js'); exports.create=function(data,callback){ var company=new Company({ Name:data.name }); company.save(function(err,company){ if(!err){ callback(null,company); } else{ callback(err,null); } }); };
在dal文件夹中,新建countryDAL.js文件,代码以下:
var Country=require('../schema/country.js'); exports.create=function(data,callback){ var country=new Country({ Name:data.name }); country.save(function(err,country){ if(!err){ callback(null,country); } else{ callback(err,null); } }); };
好了,如今是测试插入数据的时候了,方便起见,咱们定义两个路由:
一个路由在GET /company的时候插入一条数据到company集合
一个路由在GET /country的时候插入一条数据到country集合
在routes目录下,新建company.js文件,代码以下:
var express = require('express'); var router = express.Router(); var companyDAL=require('../util/dal/companyDAL'); router.get('/', function(req, res) { companyDAL.create({"name":"My Company"},function(err,result){ if(!err){ res.send(JSON.stringify(result)); } else{ res.send(err); } }); }); module.exports = router;
在routes目录下,新建country.js文件,代码以下:
var express = require('express'); var router = express.Router(); var countryDAL=require('../util/dal/countryDAL'); router.get('/', function(req, res) { countryDAL.create({"name":"My Country"},function(err,result){ if(!err){ res.send(JSON.stringify(result)); } else{ res.send(err); } }); }); module.exports = router;
而后回到app.js文件添加这两个路由:
var routes = require('./routes/index'); var users = require('./routes/users'); var company=require('./routes/company'); var country=require('./routes/country'); ............................... app.use('/', routes); app.use('/users', users); app.use('/company',company); app.use('/country',country);
最终的文件目录结构以下图:
如今咱们来测试一下:
在命令行里输入:node bin/www,能够看到下图
提示信息来自db.js,至此代表数据库已经链接成功(请各位看官记得先用mongod启动数据库)
用浏览器访问 http://http://localhost:3000/company
用浏览器访问 http://localhost:3000/country
能够看到以下的输出:
代表数据插入成功。
下面总结一下:
1. 从代码以及结果可见,在往company和country数据集插入数据的时候,都是使用的db.js中定义mongoose对象
2. db.js 在 node bin/www启动应用程序的时候就被执行,为何会被执行?
由于app.js中定义了路由并做为中间件使用
var company=require('./routes/company'); var country=require('./routes/country'); ...................... app.use('/company',company); app.use('/country',country);
而后又在路由文件(routes/company.js, routes/country.sj)中引用了数据访问层的代码
var companyDAL=require('../util/dal/companyDAL'); var countryDAL=require('../util/dal/countryDAL');
在companyDAL.js和countryDAL中又引用了schema的代码
var Company=require('../schema/company.js'); var Country=require('../schema/country.js');
在schema代码中引用了db.js
var mongoose=require('../dal/db.js');
因此在程序启动的时候db.js被调用,而且,db.js不管被引用了多少次,只会被调用一次,这是require机制决定的。
所以实现Mongoose全局数据库链接的原理是在程序启动的时候咱们就定义好数据库链接,并打开数据库链接,并把此mongoose对象做为模块的导出,其它须要使用数据库链接的时候,直接require这个模块就能够了