學(xué)習(xí)后端有兩個(gè)禮拜了。當(dāng)然,實(shí)際學(xué)習(xí)時(shí)間不過三四天,但感覺入門木有問題了,起碼我的目標(biāo):為前端提供數(shù)據(jù)支持已經(jīng)沒有問題了。其他復(fù)雜的邏輯和數(shù)據(jù)處理就等需要的時(shí)候邊學(xué)邊做吧。
在這里主要總結(jié)和探討下后端知識(shí)以及如何更快的掌握一門新技術(shù)。
Node.js學(xué)習(xí)
學(xué)習(xí)目標(biāo):為前端提供 RESTful API 接口。
Node方面,我快速瀏覽一遍基礎(chǔ)教程,對(duì)很多知識(shí)點(diǎn)都是了解即可。主要是關(guān)注在寫 RESTful 接口這一塊的知識(shí)點(diǎn):
- 全局對(duì)象 —— 了解node中經(jīng)常出現(xiàn)的全局對(duì)象是必要的。
- 常用模塊 —— 對(duì)出現(xiàn)頻率搞得模塊要熟悉的,如 fs、http、util 等
- GET、POST 請(qǐng)求和 RESTful API —— 這是我的主要學(xué)習(xí)目標(biāo),認(rèn)真看完并且照著示例代碼實(shí)現(xiàn)一遍。
- Express 框架 —— 已知的比較適合新手學(xué)習(xí)的node框架,熟悉基本用法,照著實(shí)現(xiàn)一遍。
- 連接 MongoDB —— 學(xué)習(xí)如何連接MongoDB,這個(gè)在學(xué)習(xí)了MongoDB基本知識(shí)后重點(diǎn)學(xué)習(xí)。
因?yàn)闀簳r(shí)只為了提供接口,所以只要對(duì)Node有個(gè)大致的了解。然后重點(diǎn)關(guān)注寫接口、數(shù)據(jù)庫(kù)和框架。當(dāng)我看完一遍資料,并將重點(diǎn)的知識(shí)點(diǎn)實(shí)際操作實(shí)現(xiàn)一遍之后,我對(duì) node 就有了大致了解了~達(dá)到了給我一個(gè) Node 后端項(xiàng)目我能看懂大部分代碼邏輯的程度。之后看一下 Express 框架~
Express
學(xué)習(xí)目標(biāo): 使用 Express 快速搭建 Node 后端項(xiàng)目,配合之前學(xué)到的 Node 基礎(chǔ)知識(shí)為前端提供 API 接口支持
這里把 Express 的官方文檔和API看了一遍,發(fā)現(xiàn)呢其實(shí) Express 的東西不多,在看過node基本知識(shí)后還是很好理解的。
我就用了 Express 提供的應(yīng)用生成器生成一個(gè) Express 項(xiàng)目。項(xiàng)目很簡(jiǎn)單,主要是修改 app.js 和 routes 文件夾里面的東西,寫法與Node教程里的差不多。在終端執(zhí)行 $ npm start 命令即可進(jìn)行調(diào)試。
一開始我還沒學(xué)習(xí)MongoDB的時(shí)候我是用的JSON文件來存取數(shù)據(jù)的下面是我寫的一段代碼
var express = require('express');
var fs = require('fs')
var router = express.Router();
router.get('/', function (req, res, next) {
res.send('Hello World');
});
// 獲取所有數(shù)據(jù)
router.get('/getlist', function (req, res, next) {
fs.readFile(__dirname + '/data/plan.json', 'utf8', function (err, data) {
if (err) {
res.send(err)
} else {
res.send(data)
}
})
})
router.get('/test', function (req, res, next) {
fs.readFile(__dirname + '/data/plan.json', 'utf8', function (err, data) {
var name = req.query.name
var hasVal = false
if (name == undefined) {
res.send('need name')
} else if (err) {
res.send(err)
} else {
var obj = JSON.parse(data)
for (var key in obj) {
if (obj[key].name == name) {
hasVal = obj[key]
}
}
if (hasVal) {
res.send(JSON.stringify(hasVal))
} else {
res.send('name no found')
}
}
})
})
module.exports = router;
通過 node 的文件模塊來獲取 plan.json 文件,這樣就實(shí)現(xiàn)了使用 Express 框架寫 GET 接口的目標(biāo)。訪問 http://localhost:8082/file/getlist 獲取如下結(jié)果:
[
{ "Date": "2017-6-11", "Time": "10:22", "Detail": "洗澡", "Describe": "寶寶洗干凈" },
{ "Date": "2017-6-13", "Time": "10:22", "Detail": "開飯", "Describe": "寶寶要吃飯" }
]
調(diào)試過程建議使用Postman,調(diào)試各類接口都特別方便。
數(shù)據(jù)庫(kù)
學(xué)習(xí)目標(biāo):了解 MongoDB 基本知識(shí),重點(diǎn)掌握數(shù)據(jù)的增刪改查和 MongoDB 與 Node.js 的連接
接下來轉(zhuǎn)戰(zhàn)數(shù)據(jù)庫(kù),這里選擇了 MongoDB 。在明確了學(xué)習(xí)目標(biāo)之后,重點(diǎn)學(xué)習(xí)增刪改查和數(shù)據(jù)庫(kù)連接,其他的以了解為主。就在這樣的目標(biāo)之下,重點(diǎn)學(xué)習(xí)以下知識(shí):
- 安裝、創(chuàng)建數(shù)據(jù)庫(kù)以及數(shù)據(jù)庫(kù)的一些常用操作。
- 找到一個(gè)好的數(shù)據(jù)庫(kù) GUI —— 發(fā)現(xiàn)了 Robomongo,感覺挺好用的。
- 創(chuàng)建、刪除數(shù)據(jù)庫(kù)。
- 插入、更新、查詢、刪除文檔 —— 這當(dāng)然是重中之重,所有示例逐個(gè)實(shí)現(xiàn)一遍
- 除此之外,想數(shù)據(jù)處理、比較、數(shù)據(jù)數(shù)量限制limit、排序sort等了解即可,需要的時(shí)候查閱一下就可以解決問題。
配合Node里面的 Node.js MongoDB 章節(jié),動(dòng)手實(shí)踐連接后端與數(shù)據(jù)庫(kù)了。照著教程來連接成功應(yīng)該不難。成功在 Express 項(xiàng)目中獲取到數(shù)據(jù)庫(kù)數(shù)據(jù)就說明連接成功了?,F(xiàn)在就可以開始你的表演了!
除了GET和POST,另外兩個(gè)請(qǐng)求的寫法差不多,DELETE類似GET方法,而PUT類似POST方法。
哦,對(duì)了,數(shù)據(jù)庫(kù)和node的連接所用的中間件有mongodb、mongoose等,我簡(jiǎn)單粗暴,用的最基本的MongoDB來寫的。下面是我寫的第一個(gè)后端接口代碼:
plan.js
var DBUtils = require('./DBUtils')
var express = require('express');
var fs = require('fs')
var router = express.Router();
var bodyParser = require('body-parser')
var ObjectID = require('mongodb').ObjectID
// 創(chuàng)建 application/x-www-form-urlencoded 編碼解析
var urlencodedParser = bodyParser.urlencoded({ extended: false })
router.get('/', function (req, res, next) {
res.send('Hello MongoDB');
});
router.get('/findAllPlan', function (req, res, next) {
DBUtils.getDB(function (db) {
var collection = db.collection('plan')
collection.find().toArray(function (err, result) {
if (err) {
console.log('Err:' + err)
return
}
console.log(result)
res.send(result)
db.close()
})
})
});
router.get('/findPlanByDate', function (req, res, next) {
DBUtils.getDB(function (db) {
var collection = db.collection('plan')
var Date = req.query.Date
console.log(Date)
var whereStr = { 'Date': Date }
collection.find(whereStr).toArray(function (err, result) {
if (err) {
console.log('Err:' + err)
return
}
console.log(result)
res.send(result)
db.close()
})
})
})
router.get('/findPlanById', function (req, res, next) {
DBUtils.getDB(function (db) {
var collection = db.collection('plan')
var whereStr = { '_id': ObjectID(req.query._id) }
collection.find(whereStr).toArray(function (err, result) {
if (err) {
console.log('Err:' + err)
return
}
console.log(result)
if (result.length > 0) {
res.send(result[0])
} else {
res.send({ 'msg': '未找到相應(yīng)數(shù)據(jù)' })
}
db.close()
})
})
})
router.post('/', urlencodedParser, function (req, res, next) {
DBUtils.getDB(function (db) {
var collection = db.collection('plan')
console.log(req.body)
var response = {
'Date': req.body.Date,
'Time': req.body.Time,
'Title': req.body.Title,
'Describe': req.body.Describe
}
collection.insert(response, function (err, result) {
if (err) {
console.log('Error:' + err)
return
}
res.send({ 'msg': '添加成功' })
})
})
})
router.put('/', urlencodedParser, function (req, res, next) {
DBUtils.getDB(function (db) {
var collection = db.collection('plan')
var whereStr = {
'_id': ObjectID(req.body._id),
}
var response = {
'Date': req.body.Date,
'Time': req.body.Time,
'Title': req.body.Title,
'Describe': req.body.Describe
}
collection.update(whereStr, { $set: response }, function (err, result) {
if (err) {
console.log('Error:' + err)
return
}
res.send({ 'msg': '更新成功' })
})
})
})
router.delete('/', function (req, res, next) {
DBUtils.getDB(function (db) {
var collection = db.collection('plan')
var Id = req.query.Id
var whereStr = { '_id': ObjectID(Id) }
collection.remove(whereStr, function (err, result) {
if (err) {
console.log('Error:' + err)
return
}
res.send({ 'msg': '刪除成功' })
})
})
})
module.exports = router
DBUtils.js
var MongoClient = require('mongodb').MongoClient
var DB_COUN_STR = 'mongodb://localhost:8081/etdb'// 數(shù)據(jù)庫(kù)地址
module.exports = {
getDB: function (callback) {
MongoClient.connect(DB_COUN_STR, function (err, db) {
callback(db)
})
}
}
關(guān)于跨域問題
由于都是本地服務(wù)器 localhost,遇到了跨域的問題,后來找到了最簡(jiǎn)單粗暴的方法,安裝一個(gè) cors 中間件就好了。具體用法:
$ npm install cors --save
在 app.js 中使用 cors
var cors = require('cors');
app.use(cors())
關(guān)于學(xué)習(xí)效率
學(xué)習(xí)后端和數(shù)據(jù)庫(kù)實(shí)際就花了三四天吧,感覺自己學(xué)習(xí)效率還是可以的。分享下我的學(xué)習(xí)方法。
- 明確學(xué)習(xí)目標(biāo),學(xué)習(xí)始終圍繞著目標(biāo)來。
- 快速瀏覽學(xué)習(xí)資料,找出與學(xué)習(xí)目標(biāo)有關(guān)的資料重點(diǎn)學(xué)習(xí)。
- 使用番茄時(shí)間工作法,將專注集中到一個(gè)時(shí)間段上,勞逸結(jié)合。不推薦一口氣看三四個(gè)小時(shí),效率會(huì)低下的。
- 學(xué)習(xí)技術(shù)必須邊看資料,邊敲代碼。木有實(shí)踐的知識(shí)難以理解也不容易被記住。
- 寫博客、筆記記錄總結(jié)學(xué)到的知識(shí)點(diǎn)。學(xué)會(huì)和能教是兩種境界。
總的來說,我感覺學(xué)習(xí)新技術(shù)首先是要有個(gè)目標(biāo)——學(xué)習(xí)這門新技術(shù)目標(biāo)是什么?然后根據(jù)目標(biāo)來學(xué)習(xí)。先快速瀏覽篩選出能幫我們實(shí)現(xiàn)目標(biāo)的知識(shí),然后抓重點(diǎn)學(xué)習(xí)。這樣學(xué)習(xí)才能夠快速掌握一門知識(shí)。書上說過:一本書只有20%的知識(shí)是常用的,只要掌握了這20%就可以運(yùn)用這項(xiàng)知識(shí)了,所以我們要根據(jù)目標(biāo)找準(zhǔn)那20%的知識(shí),快速入門。而那其余的80%等到需要的時(shí)候再回去查也不遲。
像我一開始學(xué)習(xí)技術(shù),幾十集教學(xué)視頻,一集集地看,每一集的實(shí)例都去實(shí)現(xiàn)一遍,結(jié)果花了一個(gè)多月才學(xué)完了課程。而在投入工作后才發(fā)現(xiàn)很多東西不常用,而且真到用的時(shí)候基本上也忘了也是要靠查資料才可以完成任務(wù)的。所以,重要的東西要重點(diǎn)學(xué),其他東西了解大概,到用的時(shí)候知道有這么回事,知道怎么查就好~
在這個(gè)技術(shù)變化極快的時(shí)代,每一門技術(shù)都不知道何時(shí)會(huì)被淘汰,所以我覺得程序員的最大財(cái)富在于學(xué)習(xí)能力和解決問題的能力,而非技術(shù)本身。所以呢,堅(jiān)持不斷地去學(xué)習(xí)和奮斗才能不被這個(gè)快速發(fā)展和變化的時(shí)代所淘汰啊~之后我會(huì)實(shí)踐更多學(xué)習(xí)新技術(shù)的過程,從中總結(jié)出一套快速學(xué)習(xí)新技術(shù)的方法來。
關(guān)于我
VioletJack,移動(dòng)、前端工程師,兩年移動(dòng)端工作經(jīng)驗(yàn)、一年前端工作經(jīng)驗(yàn)?,F(xiàn)專注于全棧開發(fā)、效率管理、學(xué)習(xí)方法的學(xué)習(xí)。會(huì)定期產(chǎn)出關(guān)于Android、Vue、移動(dòng)前端相關(guān)的博文。歡迎大家關(guān)注我,我會(huì)用心維護(hù)和經(jīng)營(yíng)好博客,多產(chǎn)出高質(zhì)量文章。同時(shí)也希望我所寫的東西可以幫到有需要的朋友。
新浪微博: http://weibo.com/u/2640909603
掘金:https://gold.xitu.io/user/571d953d39b0570068145cd1
CSDN: http://blog.csdn.net/violetjack0808
簡(jiǎn)書: http://www.itdecent.cn/users/54ae4af3a98d/latest_articles
Github: https://github.com/violetjack