注:本人因为没有翻墙,所以用的是淘宝镜像,故所有安装的命令均是cnpm install,而不是npm。个人根据需要决定是否要改为npm。
操作前先新建一个测试项目,名字随意。以mongoose-master为例,我们先创建一个mongoose-master的文件夹,然后在该文件夹下打开cmd,执行命令npm init -y.
执行前先做点准备工作,搭建一个可以浏览器访问的地址,方便测试,你可以用express或别的,我这里选择了Koa。
安装koa
1 |
cnpm install --save koa |
用koa编写一个样例
在项目根目录新建一个index.js的文件,输入如下内容:
1 2 3 4 5 6 7 8 9 10 |
const Koa = require('koa') const app = new Koa() app.use(async(ctx)=>{ ctx.body = '<h1>hello Koa</h1>' }) app.listen(3000,()=>{ console.log('[Server] starting at port 3000') }) |
然后执行命令 node index.js,再打开浏览器,访问http://loacalhost:3000,如果正常显示 hello koa 就说明 koa 已经可以正常使用了。
安装Mongoose
1 |
cnpm install mongoose --save |
连接数据库
新建一个 database 文件夹,在database文件夹下,建立一个 init.js 文件,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
const mongoose = require('mongoose') const db = "mongodb://localhost/test" // 这里改成你自己的mongodb数据库地址 mongoose.Promise = global.Promise // global是node的全局变量 exports.connect = ()=>{ //连接数据库 mongoose.connect(db) //增加数据库连接的事件监听 mongoose.connection.on('disconnected',()=>{ //进行重连 mongoose.connect(db) }) //数据库出现错误的时候 mongoose.connection.on('error',err=>{ console.log(err) mongoose.connect(db) }) //链接打开的时候 mongoose.connection.once('open',()=>{ console.log('MongoDB Connected successfully!') }) } |
修改我们一开始的 index.js
1 2 3 4 5 6 7 |
//引入connect const {connect} = require('./database/init.js') //立即执行函数 ;(async () =>{ await connect() })() |
重新执行命令 node index.js,如果能正常输出 MongoDB Connected successfully!,说明我们用 mongoose 连接数据库成功。
修改 database/init.js 的内容,我们重新创建一个加强版的连接数据库的方法,支持连接失败自动尝试重连,然后返回一个Promise,以保证其他操作都必须在数据库连接成功之后再执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
const mongoose = require('mongoose') const db = "mongodb://localhost/test" exports.connect = ()=>{ //连接数据库 mongoose.connect(db) let maxConnectTimes = 0 return new Promise((resolve,reject)=>{ //把所有连接放到这里 //增加数据库监听事件 mongoose.connection.on('disconnected',()=>{ console.log('***********数据库断开***********') if(maxConnectTimes<3){ maxConnectTimes++ mongoose.connect(db) }else{ reject() throw new Error('数据库出错误......') } }) mongoose.connection.on('error',err=>{ console.log('***********数据库错误***********') if(maxConnectTimes<3){ maxConnectTimes++ mongoose.connect(db) }else{ reject(err) throw new Error('数据库出现问题,程序无法搞定,请人为修理......') } }) //链接打开的时 mongoose.connection.once('open',()=>{ console.log('MongoDB connected successfully') resolve() }) }) } |
创建Schema
Schema 相当于 MongoDB 数据库的一个映射,主要用于对数据库各个字段类型定义,有点类似于在Java中创建一个普通的类。Schema 是一种以文件形式存储的数据库模型骨架,无法直接通往数据库端,也就是说它不具备对数据库的操作能力。Schema是以 key-value 形式Json 格式的数据。Schema中的数据类型有以下几种:
1 2 3 4 5 6 7 8 |
String :字符串类型 Number :数字类型 Date : 日期类型 Boolean: 布尔类型 Buffer : NodeJS buffer 类型 ObjectID : 主键,一种特殊而且非常重要的类型 Mixed :混合类型 Array :集合类型 |
添加一个schema文件夹,然后新建一个 User.js 文件,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
const mongoose = require('mongoose') //引入Mongoose const Schema = mongoose.Schema //声明Schema let ObjectId = Schema.Types.ObjectId //声明Object类型 //创建我们的用户Schema const userSchema = new Schema({ UserId:ObjectId, userName:{unique:true,type:String}, password:String, createAt:{type:Date,default:Date.now()}, lastLoginAt:{type:Date,default:Date.now()} }) //发布模型 mongoose.model('User',userSchema) |
操作数据库
再次修改 index.js,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
const Koa = require('koa') const app = new Koa() const mongoose = require('mongoose') const User = require('schema/User.js') const connect = require('./database/init.js') //立即执行函数 ;(async () =>{ await connect() const User = mongoose.model('User') let oneUser = new User({userName:'testuser',password:'123456'}) oneUser.save().then(()=>{ console.log('插入成功') }) console.log('------------------') let users = await User.findOne({}).exec() console.log(users) console.log('------------------') })() app.use(async(ctx)=>{ ctx.body = '<h1>hello Koa</h1>' }) app.listen(3000,()=>{ console.log('[Server] starting at port 3000') }) |
再次执行 node index.js,等控制台输出 “插入成功”时,查看我们的mongodb数据库,会发现user表已经插入了刚才的记录。
这里有个小问题,就是我们在程序中定义的是 user 而真实数据库中变成了 users,其实这也算不上问题,是mongoose在进行集合名转换的时候自动加上的,因为既然是集合,就肯定是多条记录,加个s也是情理之中。但有的朋友又不喜欢这个多出来的s,要想干掉这个多出来的s, 需要我们在用 new 创建一个 schema 的时候多加一个配置项,如下:
1 2 3 4 5 6 7 8 9 |
const userSchema = new Schema({ UserId:ObjectId, userName:{unique:true,type:String}, password:String, createAt:{type:Date,default:Date.now()}, lastLoginAt:{type:Date,default:Date.now()}, },{ collection:'user' }) |
这个的意思是帮集合指定一个自定义的名字。new Schema 的第二个参数还有很多配置项,这里就不一一列举了。mongoose的更多知识,可查看mongoose中文网。
发表评论