Nodejs開發(fā)環(huán)境的搭建
- 簡單的說 Node.js 就是運行在服務端的 JavaScript。
- V8引擎執(zhí)行Javascript的速度非巢┲快险污,性能非常好。 [1] Node.js是一個基于Chrome JavaScript運行時建立的平臺, 用于方便地搭建響應速度快蛔糯、易于擴展的網(wǎng)絡應用拯腮。Node.js 使用事件驅(qū)動, 非阻塞I/O 模型而得以輕量和高效蚁飒,非常適合在分布式設備上運行數(shù)據(jù)密集型的實時應用动壤。
應用方向
- 大型高流量網(wǎng)站都采用Node.JS進行開發(fā),
- 開發(fā)一些快速移動Web框架淮逻,
- 應用程序監(jiān)控琼懊、媒體流、遠程控制爬早、桌面和移動應用等等[2]哼丈。
以上資料均來自百度百科
使用 node -v
命令來查看當前的 Node 版本,出現(xiàn)以下情況就安裝成功
Node.js文檔 有Nodejs自帶的一些模塊。
如果需要其他的模塊凸椿,只需
npm install jquery
引入下載的模塊
var res = require("http.js");
引入自寫的模塊
var res = require("./foo.js");
更多操作和說明可參見 https://www.runoob.com/nodejs/nodejs-callback.html
Node.js 與MySQL互聯(lián)互通
MySQL操作,就不多講削祈,更多教程可參見 http://www.runoob.com/mysql/mysql-tutorial.html
MySQL不是nodejs自帶的模塊翅溺,需下載
npm install mysql
連接數(shù)據(jù)庫
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost', //主機地址 (默認:localhost)
user : 'root', //用戶名
password : '123456', //密碼
database : 'test' //數(shù)據(jù)庫名
});
connection.connect();
connection.query('SELECT * FROM login_table', function (err, result) {
});
connection.end();
使用MySQL的連接池:
var pool = mysql.createPool({
host : 'hostName',
user : 'username',
password: 'password'
});
var sql = 'SELECT * FROM websites';
pool.getConnection(function(err, connection){
connection.query(sql, function(err, rows){
});
connection.release();
});
數(shù)據(jù)庫操作( CURD ):增脑漫、刪、改咙崎、查對數(shù)據(jù)庫進行操作优幸。
//查
var sql = 'SELECT * FROM websites';
pool.getConnection(function(err, connection){
connection.query(sql, function(err, rows){
});
connection.release();
});
//增
var addSql = 'INSERT INTO websites(Id,name,url,alexa,country) VALUES(0,?,?,?,?)';
var addSqlParams = ['菜鳥工具', 'https://c.runoob.com','23453', 'CN'];
pool.getConnection(function(err, connection){
connection.query(addSql,addSqlParams,function(err, rows){
});
connection.release();
});
//改
var modSql = 'UPDATE websites SET name = ?,url = ? WHERE Id = ?';
var modSqlParams = ['菜鳥移動站', 'https://m.runoob.com',6];
pool.getConnection(function(err, connection){
connection.query(modSql,modSqlParams,function(err, rows){
});
connection.release();
});
//刪
var delSql = 'DELETE FROM websites where id=6';
pool.getConnection(function(err, connection){
connection.query(delSql,function(err, rows){
});
connection.release();
});
更多操作和說明可參見: http://www.runoob.com/nodejs/nodejs-mysql.html
可視化工具:Navicat for MySQL
demo案例 - 使用MySQL數(shù)據(jù)庫的登錄注冊系統(tǒng)
st=>start: 開始
e1=>end: 進入頁面
op1=>operation: 登錄
op2=>operation: 登錄成功
op3=>operation: 登錄失敗
op4=>operation: 注冊
op5=>operation: 注冊成功
op6=>operation: 注冊失敗
cond1=>condition: 數(shù)據(jù)庫是否存在該用戶
cond2=>condition: 數(shù)據(jù)庫是否存在該用戶
st->op1->cond1
cond1(yes)->op2->e1
cond1(no)->op3->op4->cond2->cond2(no)->op5
cond2(yes)->op6->op4
node.js與mongodb互聯(lián)互通
- MongoDB 是一個基于分布式文件存儲的數(shù)據(jù)庫。由C++語言編寫褪猛。旨在為WEB應用提供可擴展的高性能數(shù)據(jù)存儲解決方案网杆。
- MongoDB 是一個介于關系數(shù)據(jù)庫和非關系數(shù)據(jù)庫之間的產(chǎn)品,是非關系數(shù)據(jù)庫當中功能最豐富伊滋,最像關系數(shù)據(jù)庫的碳却。他支持的數(shù)據(jù)結(jié)構非常松散,是類似json的bson格式笑旺,因此可以存儲比較復雜的數(shù)據(jù)類型昼浦。Mongo最大的特點是他支持的查詢語言非常強大,其語法有點類似于面向?qū)ο蟮牟樵冋Z言筒主,幾乎可以實現(xiàn)類似關系數(shù)據(jù)庫單表查詢的絕大部分功能关噪,而且還支持對數(shù)據(jù)建立索引。 [3]
以上資料均來自百度百科
MongoDB服務的配置
- 啟動mongodb服務之前需要必須創(chuàng)建數(shù)據(jù)庫文件的存放文件夾乌妙,否則命令不會自動創(chuàng)建使兔,而且不能啟動成功。
- 創(chuàng)建數(shù)據(jù)庫文件的存放位置藤韵,比如d:/data/db;
- 在d:\data下新建文件夾log(存放日志文件)并且新建文件mongodb.log;
- 在d:\data新建文件mongo.config;
- 用記事本打開mongo.config輸入:
dbpath=D:\data\db
logpath=D:\data\log\mongodb.log
在MongoBD的bin目錄下虐沥,(也可以配置環(huán)境變量)
輸入如下的命令啟動mongodb服務:
mongod.exe --dbpath d:\data\db
如圖打開服務,出現(xiàn)以下情況則配置成功
更多操作和說明可參見:
http://www.runoob.com/mongodb/mongodb-tutorial.html
創(chuàng)建連接泽艘、集合
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function (err, db) {
if (err) throw err;
console.log('數(shù)據(jù)庫已創(chuàng)建');
var dbase = db.db("runoob");
dbase.createCollection('site', function (err, res) {
if (err) throw err;
console.log("創(chuàng)建集合!");
db.close();
});
});
數(shù)據(jù)庫操作( CURD )
//插入一條數(shù)據(jù)
//插入多條數(shù)據(jù)可以使用 insertMany():
var myobj = { name: "菜鳥教程", url: "www.runoob" };
dbase.collection("site").insertOne(myobj, function(err, res) {
if (err) throw err;
console.log("文檔插入成功");
db.close();
});
//查詢數(shù)據(jù)
//指定條件數(shù)據(jù)
var whereStr = {"name":'菜鳥教程'}; // 查詢條件
dbo.collection("site"). find(whereStr).toArray(function(err, result) { // 返回集合中所有數(shù)據(jù)
if (err) throw err;
console.log(result);
db.close();
});
// 更新一條數(shù)據(jù)
// 如果要更新所有符合條的文檔數(shù)據(jù)可以使用 updateMany():
var whereStr = {"name":'菜鳥教程'}; // 查詢條件
var updateStr = {$set: { "url" : "https://www.runoob.com" }};
dbo.collection("site").updateOne(whereStr, updateStr, function(err, res) {
if (err) throw err;
console.log("文檔更新成功");
db.close();
});
//刪除一條數(shù)據(jù)
var whereStr = {"name":'菜鳥教程'}; // 查詢條件
dbo.collection("site").deleteOne(whereStr, function(err, obj) {
if (err) throw err;
console.log("文檔刪除成功");
db.close();
})
// 如果要刪除多條語句可以使用 deleteMany() 方法
更多操作和說明可參見:https://www.runoob.com/nodejs/nodejs-mongodb.html
可視化工具下載: http://www.treesoft.cn/dms.html
demo案例 - 使用MySQL數(shù)據(jù)庫的登錄注冊系統(tǒng)
st=>start: 開始
e1=>end: 進入頁面
op1=>operation: 登錄
op2=>operation: 登錄成功
op3=>operation: 登錄失敗
op4=>operation: 注冊
op5=>operation: 注冊成功
op6=>operation: 注冊失敗
cond1=>condition: 數(shù)據(jù)庫是否存在該用戶
cond2=>condition: 數(shù)據(jù)庫是否存在該用戶
st->op1->cond1
cond1(yes)->op2->e1
cond1(no)->op3->op4->cond2->cond2(no)->op5
cond2(yes)->op6->op4
node.js與redis的互聯(lián)互通
- Redis是一個開源的使用ANSI C語言編寫欲险、支持網(wǎng)絡奈搜、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫盯荤,并提供多種
語言的API馋吗。 - Redis 與其他 key - value 緩存產(chǎn)品有以下三個特點:
- Redis支持數(shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保存在磁盤中秋秤,重啟的時候可以再次加載進行使用宏粤。
- Redis不僅僅支持簡單的key-value類型的數(shù)據(jù),同時還提供list灼卢,set绍哎,zset,hash等數(shù)據(jù)結(jié)構的存儲鞋真。
- Redis支持數(shù)據(jù)的備份崇堰,即master-slave模式的數(shù)據(jù)備份
- 優(yōu)勢
- 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
- 豐富的數(shù)據(jù)類型 – Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數(shù)據(jù)類型操作涩咖。
- 原子 – Redis的所有操作都是原子性[4]的海诲,意思就是要么成功執(zhí)行要么失敗完全不執(zhí)行。單個操作是原子性的檩互。多個操作也支持事務特幔,即原子性,通過MULTI和EXEC指令包起來闸昨。
- 豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過期等等特性蚯斯。
-
ActionScript C C++ C# Clojure Common Lisp Dart Erlang Go Haskell Haxe Io Java Node.js Lua Objective-C Perl PHP Pure Data Python R Ruby Scala Smalltalk Tcl ActionScript C C++ C# Clojure Common Lisp Dart Erlang Go Haskell Haxe Io Java Node.js Lua Objective-C Perl PHP Pure Data Python R Ruby Scala Smalltalk Tcl - 數(shù)據(jù)類型
Redis支持五種數(shù)據(jù)類型:string(字符串),hash(哈希)饵较,list(列表)拍嵌,set(集合)及zset(sorted set:有序集合)。
以上資料均來自網(wǎng)上
Window 下安裝
下載地址:https://github.com/MSOpenTech/redis/releases循诉。
Redis 支持 32 位和 64 位横辆。
Redis教程: http://www.redis.net.cn/tutorial/3501.html
可視化工具下載: http://www.treesoft.cn/dms.html
demo案例 - Nodejs+Redis+socketio的聊天室和訂閱模式
技術要點:
- 開啟服務、連接Redis數(shù)據(jù)庫
var redis = require('redis');
var http = require('http');
var socketio = require('socket.io');
// 開啟服務
var server = http.createServer(function (req, res) {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.end('服務器開啟成功');
}).listen(4000);
// 連接Redis數(shù)據(jù)庫
var redisPool = redis.createClient(6379, '127.0.0.1', {});
// 數(shù)據(jù)庫的密碼
redisPool.auth('123456');
// 共用16個數(shù)據(jù)庫
redisPool.select(1, function () {
console.log('選擇數(shù)據(jù)庫第2個數(shù)據(jù)庫');
});
redisPool.on('connect', function () {
console.log('Redis連接成功.');
})
var io = socketio(server);
io.on('connection', function (socket) {
console.log('socketio已連接成功');
// 后續(xù)的操作都這里進行
})
- 連接socketio
<script src="https://cdn.bootcss.com/socket.io/2.1.0/socket.io.js"></script>
socket = io.connect('http://127.0.0.1:4000');
socket.on('connect', function () {
// socket與后端成功建立鏈接
});
訂閱模式
- 后臺
// 消息訂閱者打洼,即subscribe客戶端龄糊,需要獨占鏈接,
var subscribe = redis.createClient();
subscribe.auth('123456');
//scoket監(jiān)聽訂閱者在客戶端訂閱一個channel
socket.on('subscribe', function (channel, username) {
//這里我們把用戶每次訂閱的channel放到了一個set中
credis.sadd('user:' + username, channel);
// 給前端發(fā)送消息
socket.emit('message', {});
subscribe.subscribe(channel);
})
- 前端
// 訂閱
var socket.emit('subscribe', channel, username);
// 接受消息
socket.on('message', function (message) {
})
取消訂閱
- 后臺
//scoket監(jiān)聽訂閱者在客戶端取消訂閱一個channel
socket.on('unsubscribe', function (channel, username) {
socket.emit('message', {});
subscribe.unsubscribe(channel);
})
- 前端
socket.emit('subscribe', channel, username);
發(fā)布消息
//消息發(fā)布者募疮,即publish客戶端炫惩,無需獨占鏈接
var publish = redis.createClient();
publish.auth('123456');
// 當前發(fā)布者向某一個channel中發(fā)布消息,
publish.publish(channel, data);
//發(fā)布者在某個channel發(fā)送消息的時候,訂閱頻道的redis鏈接監(jiān)聽這個消息和該頻道
subscribe.on('message', function (channel, message, pattern) {
socket.emit('message', {})
})
redis作為緩存對消息的存儲和查詢
根據(jù)5種數(shù)據(jù)類型有不同的存儲和查詢方法:
- string(字符串)
redisPool.set('test-key', '12354', function (err) {
});
redisPool.get('test-key', function (err, reply) {
console.log(reply);
});
- hash(哈希)
redisPool.hset('hashKey', "field1", "someValue124", redis.print);
redisPool.hmset("keys", ["test keys 1", "test val 1", "test keys 2", "test val 2"], function (err, res) {
});
redisPool.hgetall('hashKey', function (err, replies) {
console.log(replies);
});
- list(列表)
// 頭部(左邊 lpush)或者尾部(右邊 rpush)
redisPool.lpush('runoobs', "rediss", function (err, reply) {
console.log(reply);
});
redisPool.rpush('runoobs', 'valuess', function (err, reply) {
console.log(reply);
});
redisPool.lrange('runoobs', 0, 10, function (err, reply) {
console.log(reply);
});
- Set(集合)
redisPool.sadd('runoob', ['redis', '456', 'mongodb', '798'], function (err, reply) {
console.log(reply);
});
redisPool.smembers('runoob', function (err, reply) {
console.log(reply);
});
- zset(sorted set:有序集合)
redisPool.zadd('runoobz', 1, 'mongodb', function (err, reply) {
console.log(reply);
});
redisPool.zrangebyscore('runoobz', 0, 100, function (err, reply) {
console.log(reply);
});
- 升級方案(優(yōu)化)
- 增加了群發(fā)和點對點發(fā)送(以名字為唯一標識符)
- 頁面的優(yōu)化
- 對已訂閱的客戶端定時發(fā)送消息,需要socketio連接的外面執(zhí)行
setInterval(function () {
publishs.publish('訂閱者', '發(fā)布的消息');
}, 1000 * 5);
更多教程可參見: http://www.runoob.com/redis/redis-sets.html
源代碼下載地址: https://gitee.com/ityangzhiwen/knowledge-redis-mongodb-mysql
技術分享markdown頁面下載地址:https://gitee.com/ityangzhiwen/technology_sharing
-
Node.js Wiki .維基百科[引用日期2014-01-09] ?
-
NodeJS無所不能:細數(shù)十個令人驚訝的NodeJS開源項目 .TechTarget[引用日期2015-10-31] ?
-
分布式文檔存儲數(shù)據(jù)庫 MongoDB .開源社區(qū)網(wǎng)[引用日期2012-09-08] ?
-
什么是原子性,什么是原子性操作阿浓?
舉個例子:
A想要從自己的帳戶中轉(zhuǎn)1000塊錢到B的帳戶里他嚷。那個從A開始轉(zhuǎn)帳,到轉(zhuǎn)帳結(jié)束的這一個過程,稱之為一個事務筋蓖。在這個事務里卸耘,要做如下操作:
1.. 從A的帳戶中減去1000塊錢。如果A的帳戶原來有3000塊錢粘咖,現(xiàn)在就變成2000塊錢了蚣抗。
2.. 在B的帳戶里加1000塊錢。如果B的帳戶如果原來有2000塊錢瓮下,現(xiàn)在則變成3000塊錢了翰铡。
如果在A的帳戶已經(jīng)減去了1000塊錢的時候,忽然發(fā)生了意外讽坏,比如停電什么的锭魔,導致轉(zhuǎn)帳事務意外終止了,而此時B的帳戶里還沒有增加1000塊錢路呜。那么迷捧,我們稱這個操作失敗了,要進行回滾胀葱∧铮回滾就是回到事務開始之前的狀態(tài),也就是回到A的帳戶還沒減1000塊的狀態(tài)巡社,B的帳戶的原來的狀態(tài)膛堤。此時A的帳戶仍然有3000塊手趣,B的帳戶仍然有2000塊晌该。
我們把這種要么一起成功(A帳戶成功減少1000,同時B帳戶成功增加1000)绿渣,要么一起失敵骸(A帳戶回到原來狀態(tài),B帳戶也回到原來狀態(tài))的操作叫原子性操作中符。
如果把一個事務可看作是一個程序,它要么完整的被執(zhí)行,要么完全不執(zhí)行姜胖。這種特性就叫原子性。 ?