从0到1 koa-node-vue全栈开发(第六章:使用 mongoose 操作 mongodb 数据库及实战演练)

651 阅读3分钟

mongoose 操作数据库的基本方法

const mongoose = require('mongoose')
// 定义数据库地址和数据库名称 mongodb://数据库ip地址:端口号/数据库名
// mongodb://用户名:密码@127.0.0.1:27017/数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/test_1', {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useCreateIndex: true,
})

// 数据库链接成功事件之后回调
mongoose.connection.once('open', () => {
    console.log('数据库链接成功')
})

//数据库断开事件之后回调
mongoose.connection.once('close', () => {
    console.log('数据库断开连接')
});

const Schema = mongoose.Schema

const userSchema = new Schema({
    username: String,
    password: Number,
})
const user = mongoose.model('user', userSchema)

// 新增
const create = () => new Promise(resolve => {
    user.create({
        username: '小明',
        password: 123456,
    }, (err, data) => {
        if (err) {
            resolve(`新增失败: ${ err }`)
        } else {
            resolve(`新增成功: ${ data }`)
        }
    })
})

// 查找
const find = () => new Promise(resolve => {
    user.find({
        username: '小明',
    }, (err, data) => {
        if (err) {
            resolve(err)
            console.log('查找失败')
        } else {
            resolve(`查找成功${ data }`)
        }
    })
})

// 删除
const remove = () => new Promise(resolve => {
    // deleteOne删除某一个 , deleteMany批量删除
    user.deleteOne({
        _id: '5e033bdb9ba62d4a948d67f9',
    }, (err, data) => {
        if (err) {
            resolve(err);
            console.log(`删除失败`)
        } else {
            resolve(data)
        }
    })
    
})

// 更新
const update = () => new Promise(resolve => {
    // updateMany 更新全部
    user.where({ _id: '5e034af19f91f03bfc45f354' }).updateOne({
        username: '小星星',
    }, (err, data) => {
        if (err) {
            resolve(err)
            console.log('更新失败')
        } else {
            resolve(data)
        }
    })
})
const init = async () => {
    let isCreate = await create()
    let isFind = await find()
    let isRemove = await remove()
    let isUpdate = await update()
    console.log(isCreate)
    console.log(isFind)
    console.log(isRemove)
    console.log(isUpdate)
}
init()

实战: 课程表

课程列表

添加课程

本案例结合前面所学的koa,mongoose 来写一个数据库操作的案例

前端代码

<template>
    <div class="Course">
        <div class="content">
            <el-table
                :data="tableData"
                style="width: 50%;margin:20px auto;">
                <el-table-column label="课程表" align="center">
                    <el-table-column
                        prop="username"
                        label="姓名">
                    </el-table-column>
                    <el-table-column
                        prop="startTime"
                        label="开始时间">
                    </el-table-column>
                    <el-table-column
                        prop="endTime"
                        label="结束时间">
                    </el-table-column>
                    <el-table-column
                        prop="weekday"
                        label="星期">
                    </el-table-column>
                    <el-table-column align="right">
                        <template slot="header">
                            <el-button type="primary" @click="dialogFormVisible = true">添加</el-button>
                        </template>
                        <template slot-scope="scope">
                            <el-button type="primary" @click="deleteCourseItem(scope.row)">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table-column>
            </el-table>
        </div>

        <el-dialog title="课程信息" :visible.sync="dialogFormVisible">
            <el-form :model="form" label-width="80px">
                <el-form-item label="姓名">
                    <el-input v-model="form.username" style="width:220px;"></el-input>
                </el-form-item>
                <el-form-item label="开始时间">
                    <el-date-picker
                        v-model="form.startTime"
                        type="datetime"
                        placeholder="选择日期时间">
                    </el-date-picker>
                </el-form-item>
                <el-form-item label="结束时间">
                    <el-date-picker
                        v-model="form.endTime"
                        type="datetime"
                        placeholder="选择日期时间">
                    </el-date-picker>
                </el-form-item>
                <el-form-item label="日期">
                    <el-date-picker
                        v-model="form.weekday"
                        type="date"
                        placeholder="选择日期">
                    </el-date-picker>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogFormVisible = false">取 消</el-button>
                <el-button type="primary" @click="addCourse">确 定</el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script>
    export default {
        name: 'Course',
        components: {},
        data() {
            return {
                dialogFormVisible: false,
                form: {
                    username: '',
                    startTime: '',
                    endTime: '',
                    weekday: '',
                },
                tableData: [],
            }
        },
        created() {
            this.getCourseList()
        },
        computed: {},
        methods: {
            // 获取列表
            async getCourseList() {
                let { msgCode, data } = await this.$http.get('/getCourseList')
                if (msgCode === 200) {
                    this.tableData = data.map(item => ({
                        ...item,
                        startTime: this.$moment(item.startTime).format('YYYY-MM-DD HH:mm'),
                        endTime: this.$moment(item.endTime).format('YYYY-MM-DD HH:mm'),
                    }))
                }
            },
            // 添加
            async addCourse() {
                const {
                    username, startTime, endTime, weekday,
                } = this.form
                const { msgCode, message } = await this.$http.post('/addCourse', {
                    username,
                    startTime: new Date(startTime).getTime(),
                    endTime: new Date(endTime).getTime(),
                    weekday: this.$moment(weekday).weekday(),
                })
                if (msgCode === 200) {
                    this.$message.success(message)
                    this.dialogFormVisible = false
                } else {
                    this.$message.error(message)
                }
            },
            // 删除
            async deleteCourseItem(item) {
                const { _id } = item
                const { msgCode, message } = await this.$http.delete('/deleteCourseItem', {
                    // delete 携带参数需要使用data进行包裹, 后端才可以从body里面取出参数
                    data: { _id },
                })
                if (msgCode === 200) {
                    this.$message.success(message)
                    this.getCourseList()
                } else {
                    this.$message.error(message)
                }
            },
        },
    }
</script>

上面这部分代码是结合element-ui来写的一个表格, 然后写了三个接口, 分别于后端的查询, 新增, 删除对应 需要注意的就是在我们使用delete方法, 去请求接口的时候, 需要使用data来进行一层包裹, 不然后端无法从body里面拿到数据, 另外, 我并没有在前端做校验, 如果需要的话, 大家可以自己加一下

后端代码

router.js

const course = require('./controller/course')

// 添加课程
router.post('/addCourse', course.addCourse)
// 获取课程列表
router.get('/getCourseList', course.getCourseList)
// 删除单个课程
router.delete('/deleteCourseItem', course.deleteCourseItem)

./controller/course.js

const course = require('../db/module/course')
module.exports = {
    // 添加
    async addCourse(ctx, next) {
        const { request, response } = ctx
        const { body } = request
        const { username, startTime, endTime, weekday } = body
        if (username && startTime && endTime && weekday) {
            let isHave = await course.findOne({
                startTime,
                endTime,
                weekday,
                // 开始时间大于等于startTime, 结束时间小于等于endTime
            }).where('startTime').gte(startTime).where('endTime').lte(endTime)
            if (isHave) {
                response.body = {
                    msgCode: 400,
                    message: '该课程已存在, 不能重复添加',
                }
            } else {
                const result = await course.create({
                    username,
                    startTime,
                    endTime,
                    weekday,
                })
                response.body = {
                    msgCode: 200,
                    message: '课程添加成功',
                    data: result,
                }
            }
        } else {
            response.body = {
                msgCode: 400,
                message: '请完善表单',
            }
        }
        // 先去查找数据库, 如果有就不能添加, 如果找不到, 则返回null
    },
    // 获取所有
    async getCourseList(ctx, next) {
        const { request, response } = ctx
        const list = await course.find()
        response.body = {
            msgCode: 200,
            message: '',
            data: list,
        }
    },
    // 删除
    async deleteCourseItem(ctx, next) {
        const { request, response } = ctx
        const { body } = request
        const { _id } = body
        const { deletedCount, ok } = await course.deleteOne({
            _id,
        })
        if (ok && deletedCount) {
            response.body = {
                msgCode: 200,
                message: '删除成功',
            }
        } else {
            response.body = {
                msgCode: 400,
                message: '删除失败',
            }
        }
    },
}

这个js文件里面的内容, 我们还可以将对数据库的操作抽取出来, 使内容更加简洁, 也更方便我们维护, 但是这里为了大家能看的更清楚, 所以我就不抽取文件了, 在最后一章的综合实例上, 我将重新将文件进行抽取划分

/db/module/course.js

const mongoose = require('mongoose')
const Schema = mongoose.Schema

const courseSchema = new Schema({
    username: String,
    startTime: {
        type: Date,
        require: true,
    },
    endTime: {
        type: Date,
        require: true,
    },
    weekday: {
        type: Number,
        max: 6,
        min: 0,
    },
})
module.exports = mongoose.model('course', courseSchema)

这一章我们先通过连接数据库, 然后再通过前后端对数据库进行操作, 让我们明白了如何使用mongoose去操作数据库, 也知道前后端的交互是什么样的方式. 下一章我将会讲解一下日志, 然后, 通过实例, 来演示日志的作用