koa mogoose 建立後臺服務鏈接數據庫並進行增刪改查

本文原創 ,轉載請標明出處javascript

1 koa的基本使用html

koa是基於node平臺的web開發框架java

使用koa去建立一個服務器node

const Koa = require('koa')
// bodyParser 處理post請求
const bodyParser = require('koa-bodyparser')
const port = 7001
const app = new Koa()

app.use(bodyParser())
app.use(async ctx => {
  ctx.body = 'hello , i am first koa applicance'
})

app.listen(port)

koa 使用 下面方式 利用ctx.body將內容或接口數據返回給到頁面,若做爲接口時,未寫ctx.body接口將報錯404 Not Foundmysql

app.use(async ctx => {
  ctx.body = ''
})

下面一個從後臺獲取數據返回給到頁面 的demo(做爲中間層)git

const Koa = require('koa')
// bodyParser 處理post請求
const bodyParser = require('koa-bodyparser')
// 用於請求後臺數據 當咱們想把改服務做爲web和後臺的中間層時 須要使用request-promise 或者request 固然還有其餘的
const request = require('request-promise')
const port = 7001
const app = new Koa()

app.use(bodyParser())

// 向後臺發起請求
let _callApi = (url, datas, headers) => {
  // 本文以POST請求爲例說明,其餘方式請參閱request-promise官方文檔
  let options = {
    uri: url,
    method: 'POST',
    body: datas,
    json: true,
    timeout: 10000
  }
  if (headers) {
    options.headers = headers
  }
  return new Promise((resolve, reject) => {
    request(options)
      .then(res => {
        resolve(res)
      })
      .catch(err => {
        reject(err)
      })
  })
}

app.use(async ctx => {
  ctx.body = 'hello , i am first koa applicance'
})

app.use(async ctx => {
  let queryUrl = ctx.request.url.split('?')[0]
  if (queryUrl === '/mytest/testpost') {
    let data = ctx.request.body
    let response = await _callApi('apiUrl', data)
    ctx.body = response
  }
})
app.listen(port)

使用 ctx.request 將web端請求的內容拿到,根據本身的需求組裝 將內容發送給後臺獲取接口數據 能夠自行打印ctx.requestgithub

注意:A 當在項目中使用session時 須要有配置文件而且給app設置keys web

// 存儲 內容
const CONFIG = {
  overwrite: false,
  maxAge: 7200000 //過時時間設置兩個小時
}
app.keys = ['myvars is changing']
app.use(session(CONFIG, app))

// 在接口中存數據
ctx.session.username = 'myName'
// 在接口中去數據
let userName =  ctx.session.username

    B:項目中使用cookiessql

const Koa = require('koa');
const app = new Koa();

app.use(async ctx=>{
    if(ctx.url === '/public'){
        ctx.cookies.set(
            'name', 'public', {
                domain: 'localhost',
                path: '/public',
                // 有效時長 表示從Date.now()獲得的毫秒值
                maxAge: 24 * 60 * 60 * 1000,
                // cookies 過時的date
                expires: new Date('2018-12-31'),
                // 服務器可訪問cookie 默認true
                httpOnly: false,
                // 是否覆蓋之前設置的同名的cookie默認false 
                overwrite: false
            }
        );
        ctx.body = 'cookie success';
    }else{
        ctx.body = 'no cookie';
    }
});

app.listen(3000, () => {
    console.log('服務開啓成功在3000端口');
});

 

固然 當咱們接口不少時 可使用koa-router進行路由的定義 ,koa-router支持不少接口方式mongodb

  router.get('/users', ctx => {
    // ....
  })
  router.post('/users', ctx => {
    // ....
  })
  .put('/user/:id', ctx => {
    // ....
  })
  .del('/user/:id', ctx => {
    // ....
  })
  .all('/user/:id', ctx => {
    // ....
  });

koa-router 引入方式:

const Router = require('koa-router')
const router = new Router()
//或者下面的方式
const router = require('koa-router')()
// router裝載 routes表明可能多個
app.use(router.routes());
// 如get 就只能用get進行請求 使用post將會報錯405 Method Not Allowed;
app.use(router.allowedMethods());

  

2 mongodb 的基本用法

mongodb的安裝請參見菜鳥教程:https://www.runoob.com/mongodb/mongodb-window-install.html 或者參見其餘

(安裝教程不一樣的是現有的 安裝包下載完直接默認了 data和log的存放地址 能夠自定義修改), 安裝完成能夠經過mongod 命令查看

  開始使用:命令行輸入 mongo 以後就能夠進行增刪改查;

 也能夠在當前bash目錄下寫js文件 去鏈接數據庫進行增刪改查;執行命令 load(‘文件名’),好比dboper.js:

var userName = "testtwo";
var time = Date.parse(new Date());
var data = {
    "title": userName,
    "registTime": time
};
var db = connect('testtwo');
db.testtwo.insert(data);
print('insert success');
命令行輸入load('dboper.js')  ,當控制檯打印 insert success 即運行成功
 
  A.數據庫
       建立 : use myDbone(數據庫沒有,將被建立,可是show dbs時不顯示,由於是空的,須要插入內容才能夠)
       查看: db (看當前使用的所在的數據庫)或 show dbs(看全部數據庫)
       刪除:db.dropDatabase(),刪除當前數據庫,演示以下:
use testone
switched to db testone
db
testone
db.dropDatabase()
{ "dropped" : "testone", "ok" : 1 }

  B 集合 (至關於mysql的表格)
      建立集合:db.createCollection(name, options) options可選 指定內存的大小索引等 詳細信息見官網或菜鳥教程
      查詢集合:show tables 或 show collections
      刪除集合: db.myColl.drop()

  C 文檔 (至關於mysql的行)
      插入文檔:db.myColl.insert({title:‘myFirst’,url:'www.baidu.com'}或者變量名)
 
      查找文檔:db.myColl.find()   //查找全部
                      db.myColl.findOne()   //查找第一條數據
                      db.myColl.find({title:‘myFirst’})   //條件查詢
                      db.myColl.find().limit()  // 限制訪問的數量
                      db.myColl.find().skip()  // 跳過多少去訪問 用limit和skip能夠實現分頁的效果
                      db.myColl.find().sort({age:1})   //1 按age升序排列, -1 按降序排列
      
//數據查詢find
$gte: 大於等於
$lte: 小於等於
  db.user.find(
    // 查詢條件
    {age: {$gte: 20, $lte: 30}},
    // 顯示的字段名稱
    {name: true, age: true, _id: false}
  )

$in: 數組內等於20和等於25
  db.user.find(
    {age: { $in: [20, 25]}}, //等於20 和25的
    {name: true, age: true, _id: false}
  )

$or $and 
  db.user.find({
    $and/$or: [
        {age: { $gte: 20}},
        {'pc.brand': 'IBM'}
    ]},
    {name: true, age: true, _id: false}
  )
  db.user.find(
    // hobby中包含籃球
    {hobby: '籃球'},
    // hobby只是籃球,
    // {hobby: ['籃球']},
    {name: true, age: true, _id: false}
  );

$all 以下既喜歡籃球又喜歡敲代碼 若爲$in則是或的關係
  db.user.find(
    {hobby: {$all: ['籃球', '敲代碼']}},
    {name: true, age: true, _id: false}
  );

$size 按照數組的長度去查詢
  db.user.find(
    {hobby: {$size: 3}},
    {name: true, age: true, _id: false}
  );

limit 每次查詢多少條
skip 跳過多少條
sort 按那個字段進行排序 1和-1
  db.user.find(
    {},
    {name: true, age: true, _id: false}
  ).limit(1).skip(1).sort({age: -1})
 
      更新文檔:db.myColl.update({title:myFirst},{$set:{title:'myFirltUpdate'}}) 按條件查找內容並進行替換
                      db.myColl.updateOne({})
數據更新
$set 修改指定的能夠值
  db.myColl.update({ name:'lxh' },{ $set:{ 'age':18 }})
$unset 刪除一個keyvalue值 name=lxh這條數據裏面將沒有age這個key和value值
  db.myColl.update({ name:'lxh' },{ $unset:{ 'age': ''}})
upsert(更新插入) 好比下面有age值就去更新,沒有就去插入這個值
  db.myColl.update({ name:'lxh' },{ $set:{ age:18 }},{upsert:ture})
multi 全部文檔都加上hobby屬性,multi:false只有第一條數據會加
  db.myColl.update({},{$set:{hobby:['code']}},{multi:true})
$push 給文檔裏面的某個屬性push內容,須要時數組格式
  db.myColl.update({name:'lxh'},{$push:{hobby:'chiji'}})
$addToSet  查找內容是否已存在,存在了就不加,不存在就push
  db.myColl.update({name:'lxh'},{$addToSet:{hobby:'sleep'}})
$each 
  db.myColl.update({name:'lxh'},{$addToSet:{hobby:{$each:['sleep','wake up']}}})
$set
  db.myColl.update({name:'lxh'},{$set:{'hobby.0':'sport'}})
findAndModify 查找而且修改(上面不會返回任何內容,該方法應答式的)
  var modify = {
    findAndModify: 'user',  //應答式的,會返回操做結果
    query: {name: 'lxh'},
    update: {$set: {age: 22}},
    new: true //true 更新後的結果,false更新前的結果
  };
     
        刪除文檔:db.myColl.remove({title:myFirstUpdate}) 刪除查找到的內容
                      db.myColl.remove({}) 刪除全部文檔
      db.myColl.drop() //刪除全部內容(整個集合)
 
        數據庫的索引:
            生成隨機索引(須要頻繁查詢時須要創建索引加快查詢速度,可是同時會增長磁盤的消耗,在寫入和更新數據時會必定程度的下降寫入想能)
               db.myColl.ensureIndex({username:1})
            查詢索引
               db.myColl.getIndexes()  
            刪除當前索引
               db.myColl.dropIndex({username:1})

3 koa 鏈接mongodb 進行鏈接數據庫並增刪改查,mongoose是Node和MongoDB數據通信的數據建模庫

npm install mongoose --save

  A  使用mongoose.connect鏈接數據庫 

const mongoose = require('mongoose')
//testone 是本身建的db
const DB_URL = 'mongodb://127.0.0.1:27017/testone'

mongoose.connect(DB_URL, {
  useNewUrlParser: true,
  useUnifiedTopology: true
})
var db = mongoose.connection
db.on('connected', function() {
  console.log('Mongoose connection open to ' + DB_URL)
})

// 鏈接異常數據庫報錯
db.on('error', function(err) {
  console.log('Mongoose connection error:' + err)
})

// 鏈接斷開 disconnected 鏈接異常斷開
db.on('disconnected', function() {
  console.log('Mongoose connection disconnected')
})

module.exports = mongoose

  注意:鏈接數據庫時 不設置 useNewUrlParser: true,useUnifiedTopology: true 會致使報錯 過期的 告訴你須要經過設置這個 來進行兼容

  B 使用mongoose.Schema 去建立數據表裏面的各個字段和類型,每一個mongoose都是從Schema開始,映射到MongoDB集合

const Schema = mongoose.Schema

const testSchema = new Schema({
  name: String,
  age: Number,
  studentId: { type: String, unique: true }  //設置了unique 爲true新建時傳入重複的值會提示E11000 duplicate key error collection***
})

  C 使用Model  將Schema 和底層MongoDB數據庫鏈接到一塊兒,model的實例就是文檔,model負責從底層MongoDB數據庫建立和讀取文檔

const Student = mongoose.model('testone', testSchema)

 D 建立本身的類 封裝增刪改查功能

class StudentDb {
  constructor() {}
  // 查詢
  query(obj) {
    return new Promise((resolve, reject) => {
      Student.find({}, (err, res) => {
        // Student.find({ age: { $gte: 22, $lt: 25 } }, (err, res) => {   //按條件去查詢
        if (err) {
          reject(err)
        }
        resolve(res)
      })
        .limit(obj.pageSize) // 限制訪問的數量
        .skip(obj.pageSize * (obj.pageNum - 1)) // 跳過多少去訪問 用此能夠實現分頁的效果
        .sort({ age: 1 }) //1 按age升序排列, -1 按降序排列
    })
  }
  // 保存
  save(obj) {
    const m = new Student(obj)
    return new Promise((resolve, reject) => {
      m.save((err, res) => {
        if (err) {
          reject(err)
        }
        resolve(res)
        console.log(res)
      })
    })
  }
  // 按studentId查詢
  where(obj) {
    const query = JSON.parse(JSON.stringify(obj))
    return new Promise((resolve, reject) => {
      Student.find({ studentId: query.studentId }, (err, res) => {
        if (err) {
          reject(err)
        }
        resolve(res)
      })
    })
  }
  // 更新
  update(obj) {
    const query = JSON.parse(JSON.stringify(obj))
    return new Promise((resolve, reject) => {
      Student.updateOne({ _id: query._id }, { $set: query }, (err, res) => {
        if (err) {
          reject(err)
        }
        resolve(res)
        console.log('update=====', res)
      })
    })
  }
  // 刪除
  del(obj) {
    const query = JSON.parse(JSON.stringify(obj))
    return new Promise((resolve, reject) => {
      Student.remove({ studentId: query.studentId }, (err, res) => {
        if (err) {
          reject(err)
        }
        resolve(res)
        console.log(res)
      })
    })
  }
}

  E 導出這個類在其餘的地方使用

module.exports = new StudentDb()

 F 在須要的文件中引入 並使用

const StudentDb = require('./index')   //上面類定義的文件

 G 利用koa-router 以及上面封裝的方法進行數據庫的操做

// 查詢全部內容接口
router.get('/testMogodb/query', async ctx => {
  // const queryPars = ctx.request.body
  const queryPars = {
    pageSize: ctx.request.body.pageSize,
    pageNum: ctx.request.body.pageNum
  }
  let data = await StudentDb.query(queryPars)
  ctx.body = data
})
// 按條件查詢接口
router.post('/testMogodb/search', async ctx => {
  const queryPars = ctx.request.body
  console.log('queryPars', queryPars)
  let data = await StudentDb.where(queryPars)
  ctx.body = data
})
// 添加接口
router.post('/testMogodb/add', async ctx => {
  const studentObj = {
    name: ctx.request.body.name,
    age: ctx.request.body.age,
    studentId: ctx.request.body.studentId
  }
  let code, message
  try {
    await StudentDb.save(studentObj)
    code = 0
    message = 'Add successful'
  } catch (error) {
    code = -1
    message = error || 'Add failure'
  }
  ctx.body = {
    code,
    message
  }
})
// 更新已有內容的接口
router.post('/testMogodb/update', async ctx => {
  let code, message
  const result = await StudentDb.update({
    name: ctx.request.body.name,
    age: ctx.request.body.age,
    studentId: ctx.request.body.studentId,
    _id: ctx.request.body._id
  })
  try {
    await result
    code = 0
    message = 'Update successful'
  } catch (error) {
    code = -1
    message = error || 'Update failure'
  }
  ctx.body = {
    code,
    message
  }
})
// 刪除指定內容接口
router.post('/testMogodb/del', async ctx => {
  const studentObj = {
    // _id: ctx.request.body._id
    studentId: ctx.request.body.studentId
  }
  let code, message
  try {
    await StudentDb.del(studentObj)
    code = 0
    message = 'Delete successful'
  } catch (error) {
    code = -1
    message = error || 'Delete failure'
  }
  ctx.body = {
    code,
    message
  }
})  

 注意 上面router使用過程當中 async await 語法的使用;

詳細代碼地址:https://github.com/liangxianh/koa-mongoose.git 

參考地址:官方文檔https://mongoosejs.com/docs/index.html

相關文章
相關標籤/搜索