本文原創 ,轉載請標明出處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');
use testone switched to db testone db testone db.dropDatabase() { "dropped" : "testone", "ok" : 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})
數據更新 $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更新前的結果 };
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