egg學習(一):使用egg的egg-mongoose搭建本地數據庫

搭建一個egg項目:
代碼地址:demo

結合node搭建本地服務器的框架有很多,今天選擇的是egg這個框架,他是koa框架的封裝形式,用起來會比較小白一點。由於本人用的是MongoDB搭建本地的數據庫,所以選擇了egg的egg-mongoose模塊來搭建項目

安裝egg的初始化框架
$ npm i egg-init -g
$ egg-init egg-example --type=simple
$ cd egg-example
$ npm i
啓動項目
$ npm run dev
$ open localhost:7001
鏈接到本地的MongoDB:

安裝mongoose並引入到項目中

npm install egg-mongoose -S
  • 在config文件中找到 config.default.js 文件
// 引入egg-mongoose
const mongoose = require('mongoose');
module.exports = appInfo => {
  const config = exports = {};
  config.keys = appInfo.name + '_1539588102822_7832'; // 此處的字符是自己設定的cookie加密碼
  // 添加 view 配置,nunjucks是一個用來在服務器端渲染HTML的插件,用npm 安裝即可
  exports.view = {
    defaultViewEngine: 'nunjucks',
    mapping: {
      '.tpl': 'nunjucks',
    },
  };
  exports.mongoose = {
    url: 'mongodb://127.0.0.1:27017/mongoTest',
    // 鏈接到本地的MongoDB,mongoTest是我本地數據庫的名字,根據自己數據庫名字進行填寫即可
    options: {},
  };
  // add your config here
  config.middleware = [];
  return config;
};

介紹項目目錄分配

在egg 項目的app文件中,有系統默認的幾個文件夾
在這裏插入圖片描述

  • controller : 是用來分發路由接口請求的文件夾,指定了不同的路由對應的操作
  • middleware : 是用來存放中間件的文件夾
  • model : 是用來定義數據庫中表單的數據類型的文件夾
  • service : 是用來操作數據庫的文件存放的地方,他是從controller中細化出來的,主要用來寫一些sql語言,保持 Controller 中的邏輯更加簡潔。
  • view : 是用來存放一些需要服務器渲染的頁面的.html.tpl文件的地方
  • router :是用來分配接口路由的文件
  • router.js :爲了讓router 文件夾中的路由文件看起來整潔有明確的分類,在外層用router.js這樣一個文件做一個入口和索引的作用

介紹了以上的文件夾的作用,就可以開始寫自己的後臺項目了,每個模塊對應的命名有一定的要求,比如我現在要創建一個關於學生選修課的接口,我先創建一個學生的數據庫表格,我給文件命名爲student,那麼我就需要在controller,service,model中創建一個student.js,入門級的使用方式可以參照 egg快速入門

第一步:分配路由:(在router.js文件中)

module.exports = app => {
  const { router, controller } = app;
  router.get('/getStudentList', controller.student.list); 
  // 1、我定義這個接口是獲取表格中所有學生的信息, 這是一個get請求
  // 2、對應的是controller下面的student.js文件裏面的list方法
  router.post('/add', controller.student.add);
  // 這是一個post請求,調用的是controller裏面的add方法
};

那麼我就需要在controller文件夾下面創建一個student.js文件,並在裏面創立一個list方法,因爲controller對應的是不同路由的操作的文件夾,所以這裏當我們接收到對應的路由請求之後,對數據路進行對應的操作

// app/controller/student.js
const Controller = require('egg').Controller;

class UserController extends Controller {
// 這裏的 list 就是上面 controller.student.list 裏面的 list
  async list() {
    const ctx = this.ctx;
    var aa = await ctx.service.student.list()
    // 爲了方便文件的管理,當後續controller的方法變多的時候,操作數據庫的語言就不適合都擠在一個文件裏面,所以egg框架的service文件夾就起到了分配壓力的作用,所有具體的sql操作會寫在service文件夾中,我也是爲了方便操作的複用。
    // 此處我們調用的是 service 文件夾裏面的student.js 文件裏面的 list方法
    // 調用玩這個方法後,會返回一個數據庫中查找出來的數據,我們用變量 aa 來接收
    ctx.body = aa
    // 將接收到返回的數據渲染出來,也可以用return的方式放回給前端
  }
}
module.exports = UserController;

在上面的操作中我們需要調用service文件夾裏面的student.js裏面的list方法,那麼我們就要在service文件夾裏面創建一個student.js文件

// app/service/student.js
const Service = require('egg').Service;

class UserService extends Service {
  async list() {
    const ctx = this.ctx;
    return ctx.model.Student.find({})
    // ctx.model.Student.find({"title":"111"}) 表示在數據庫中查找title 爲111的對應數據
  }
}
module.exports = UserService;

現在controllerservice裏面都有student.js文件了,還有model 裏面需要,我們需要在model中規定數據庫的數據類型,防止錯誤格式的儲存

// app/model/student.js
module.exports = app => {
  const mongoose = app.mongoose;
  const Schema = mongoose.Schema;
 
  const UserSchema = new Schema({
    studentName: { type: String, required: true },
    age: { type: Number},
    gender:{type : String, enum:['男','女']},
    phone:{
	    type:String,
	      validate: {
	        validator: function(v) {
	          if(v.length < 8){
	            return false
	          }
	        },
	        message: '${v} is not a valid phone number!'
	      }, 
	    }
  });
  // 以上定義了表數據的類型
 
  return mongoose.model('student', UserSchema,'studentInfo');
  // model(參數1,參數2,參數3)參數3是你數據表中需要操作的表的名字,
  // 比如我現在要操作的是名字叫mongoTest裏面的叫studentInfo的表
}

npm run dev 運行項目~
可以利用 postman 進行請求的模擬:
我的數據庫表單裏面有三條信息:(這是mongodb的一個可視化工具,叫Mongo compass,可以百度一下具體使用方法。
在這裏插入圖片描述

這就是你本地數據庫裏面獲取到的信息,也可以寫一個增加數據

這個是查詢的功能,我們還會有增刪改,其中增刪改都會涉及到數據操作是成功還是失敗的信息的返回,我們就以增加數據來舉例:
還是第一步:分配路由

module.exports = app => {
  const { router, controller } = app;
  router.get('/getStudentList', app.controller.student.list);
  // 添加學生信息
  router.post('/add', app.controller.student.add);
  // 學生信息更新
  router.post('/edit', app.controller.student.edit);
};

然後是去controller的user.js裏面添加add方法:

// app/controller/user.js
const Controller = require('egg').Controller;

class UserController extends Controller {
// 這裏的 list 就是上面 controller.user.list 裏面的 list
  async list() {
    const ctx = this.ctx;
    var aa = await ctx.service.student.list()
    // 此處我們將操作數據庫,所以調用的是 service 文件夾裏面的user.js 文件裏面的 list方法
    // 調用玩這個方法後,會返回一個數據,我們用 aa 來接收
    ctx.body = aa
    // 將接收到返回的數據渲染出來
  }
  // 添加用戶
  async add() {
    const ctx = this.ctx;
    const req = ctx.request.body
    // 獲取請求體的內容
    ctx.body = await ctx.service.student.add(req);
  }
}
module.exports = UserController;

然後是service文件夾:

// app/service/user.js
const Service = require('egg').Service;

class UserService extends Service {
  async list() {
    const ctx = this.ctx;
    return ctx.model.Student.find({})
    // ctx.model.User.find({"title":"111"}) 表示在數據庫中查找title 爲111的對應數據
  }
  // 添加用戶
  async add(req) {
    const ctx = this.ctx
    return ctx.model.Student.create(req).then(res => {
      return { success: true, msg: res, code: 0 };
    }).catch(err => {
      return { success: false, err };
    });
  }
}
module.exports = UserService;

發送請求,然後報錯,gg
在這裏插入圖片描述
請教了一下同行,說是需要在 config 文件夾的 config.default.js 中加上這個:

const config = exports = {
    security: {
      csrf: {
        enable: false
      }
    }
  };

因爲之前在model中已經定義了數據表的數據類型,這裏就不需要再定義,直接上postman測試:
在這裏插入圖片描述
拿到自定義的返回內容,表示插入成功!再打開Mongo compass 查看一下數據表:

在這裏插入圖片描述
如果在真正的項目開發中,需要寫的接口特別的多,需要對路由進行分配和歸類,我們可以在 app 文件夾下創建一個子文件,叫做 route
此時更改一下router.js文件內容:

'use strict';
/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  require('./route/student')(app)
  // 我將之前所有跟用戶信息相關的路由操作都放在一個類別中
};

在route文件夾中創建一個user.js的文件

// app/route/student.js
module.exports = app => {

  // 
  app.router.get('/getStudentList', app.controller.student.list);
  // 添加用戶信息
  app.router.post('/add', app.controller.student.add);

};

運行一次,得到之前同樣的效果。這樣寫在遇到大量接口的時候會更加清晰簡潔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章