Mercer-Lee的空间

vuePress-theme-reco Mercer-Lee的空间    2018 - 2024
Mercer-Lee的空间 Mercer-Lee的空间

Choose mode

  • dark
  • auto
  • light
TimeLine
分类
  • 数据结构和算法
  • 后端
  • 运维
  • 前端
  • 工具
  • 语言
标签
我的GitHub (opens new window)
author-avatar

Mercer-Lee的空间

27

文章

29

标签

TimeLine
分类
  • 数据结构和算法
  • 后端
  • 运维
  • 前端
  • 工具
  • 语言
标签
我的GitHub (opens new window)
  • Egg配合MongoDB日常开发和注意事项

    • 连接 MongoDB
      • 创建 Schema
        • 操作数据库
          • 注意事项

          Egg配合MongoDB日常开发和注意事项

          vuePress-theme-reco Mercer-Lee的空间    2018 - 2024

          Egg配合MongoDB日常开发和注意事项


          Mercer-Lee的空间 2019-11-03 Egg JS MongoDB Node

          # 连接 MongoDB

          这里我们先安装 ORM:

          $ npm install egg-mongoose
          

          然后分别在插件文件和配置文件声明:

          // config/config.default.js
          
          "use strict";
          
          module.exports = appInfo => {
            // 数据库配置
            config.mongoose = {
              url: "mongodb://localhost:27017/demo",
              options: {
                useCreateIndex: true,
                useNewUrlParser: true,
                useUnifiedTopology: true,
                useFindAndModify: false // 可以关闭findOneAndUpdate()、findOneAndDelete()这些弃用API的警告
              }
            };
          
            return {
              ...config
            };
          };
          
          // config/plugin.js
          
          "use strict";
          
          exports.mongoose = {
            enable: true,
            package: "egg-mongoose"
          };
          

          # 创建 Schema

          在 app 目录下建立 model 目录,然后添加 user.js 文件

          // app/model/user.js
          
          module.exports = app => {
            const mongoose = app.mongoose;
            const { Schema } = mongoose;
          
            const userSchema = new Schema({
              username: { type: String, required: true, minlength: 3 },
              password: { type: String, required: true },
              avatar: { type: String, default: "" },
              email: { type: String, default: "" }
            });
          
            userSchema.index({ username: 1 }, { unique: true });
            userSchema.index({ email: 1 }, { unique: true });
          
            return mongoose.model("User", userSchema);
          };
          

          # 操作数据库

          然后我们在 service 下试着写一下对于 MongoDB 的操作:

          // app/service/user.js
          
          "use strict";
          
          const Service = require("egg").Service;
          
          class UserService extends Service {
            async addUser(userData) {
              return new this.ctx.model.User(userData).save();
            }
          
            async getUserOne(conditions) {
              return this.ctx.model.User.findOne(conditions);
            }
          }
          
          module.exports = UserService;
          

          接着在 controller 写注册用户的逻辑:

          "use strict";
          
          const Controller = require("egg").Controller;
          
          class UserController extends Controller {
            constructor(ctx) {
              super(ctx);
          
              this.userValidate = {
                email: { type: "email" },
                password: { tpe: "password", required: true, min: 5 },
                username: { type: "string", required: true, min: 3 }
              };
            }
          
            /**
             * @description 注册
             */
            async register() {
              const { ctx, service } = this;
              ctx.validate(this.userValidate, ctx.request.body);
              const { username, password, email } = ctx.request.body;
              password = ctx.genHash(password);
              const user = await service.user.getUser({ $or: [{ username }, { email }] });
              if (!user) {
                await service.user.addUser({
                  username,
                  password,
                  email
                });
                ctx.helper.success({ ctx });
              } else {
                ctx.throw(422, "用户已经存在");
              }
            }
          }
          
          module.exports = UserController;
          

          最后在 router 挂载对应的 controller:

          "use strict";
          
          module.exports = app => {
            const { router, controller } = app;
          
            router.post("/user/loginRegister/register", controller.user.register);
          };
          

          # 注意事项

          如果是以前有过 express 开发经验的朋友,肯定有一些很喜欢在 mongoose 的操作里面写回调函数,但是在 egg 或其他基于 koa 的框架中是不建议这么做的。因为 koa 抛弃了传统的 callback,而拥抱了 async,所以日常的开发中我们需要抛弃掉 express 的开发思想,调用异步 service 的时候 async 和 await 的组合更有效且安全。如果是同时调用几个异步 service,那么 Promise.all()是一个很好的解决方案。比如:

              /**
               * @description 获取用户发表过的文章
               */
              async getUserArticle() {
                  const { ctx, service } = this;
                  const { _id: userId } = await service.user.veriifyToken({ required: true });
                  const { articleId } = ctx.query;
                  const { numberOfPage } = ctx.params;
                  const article = service.article.getArticleListTimeLine({ author: userId }, articleId, Number(numberOfPage));
                  const articleLength = service.article.getArticleListCount({ author: userId });
                  await Promise.all([article, articleLength]).then(res => {
                      const [article, articleLength] = res;
                      ctx.helper.success({ ctx, data: { article, articleLength } })
                  })
              }