Nodejs开发环境的搭建
- 简单的说 Node.js 就是运行在服务端的 JavaScript。
- V8引擎执行Javascript的速度非常快,性能非常好。 [1] Node.js是一个基于Chrome JavaScript运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞I/O 模型而得以轻量和高效,非常适合在分布式设备上运行数据密集型的实时应用。
应用方向
- 大型高流量网站都采用Node.JS进行开发,
- 开发一些快速移动Web框架,
- 应用程序监控、媒体流、远程控制、桌面和移动应用等等[2]。
以上资料均来自百度百科
下载:Node.js 中文网
使用 node -v
命令来查看当前的 Node 版本,出现以下情况就安装成功
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互联互通
MySQL操作,就不多讲,更多教程可参见 http://www.runoob.com/mysql/mysql-tutorial.html
MySQL不是nodejs自带的模块,需下载
npm install mysql
连接数据库
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost', //主机地址 (默认:localhost)
user : 'root', //用户名
password : '123456', //密码
database : 'test' //数据库名
});
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();
});
数据库操作( CURD ):增、删、改、查对数据库进行操作。
//查
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数据库的登录注册系统
st=>start: 开始
e1=>end: 进入页面
op1=>operation: 登录
op2=>operation: 登录成功
op3=>operation: 登录失败
op4=>operation: 注册
op5=>operation: 注册成功
op6=>operation: 注册失败
cond1=>condition: 数据库是否存在该用户
cond2=>condition: 数据库是否存在该用户
st->op1->cond1
cond1(yes)->op2->e1
cond1(no)->op3->op4->cond2->cond2(no)->op5
cond2(yes)->op6->op4
node.js与mongodb互联互通
- MongoDB 是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
- MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。 [3]
以上资料均来自百度百科
MongoDB服务的配置
- 启动mongodb服务之前需要必须创建数据库文件的存放文件夹,否则命令不会自动创建,而且不能启动成功。
- 创建数据库文件的存放位置,比如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目录下,(也可以配置环境变量)
输入如下的命令启动mongodb服务:
mongod.exe --dbpath d:\data\db
如图打开服务,出现以下情况则配置成功
更多操作和说明可参见:
http://www.runoob.com/mongodb/mongodb-tutorial.html
创建连接、集合
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function (err, db) {
if (err) throw err;
console.log('数据库已创建');
var dbase = db.db("runoob");
dbase.createCollection('site', function (err, res) {
if (err) throw err;
console.log("创建集合!");
db.close();
});
});
数据库操作( CURD )
//插入一条数据
//插入多条数据可以使用 insertMany():
var myobj = { name: "菜鸟教程", url: "www.runoob" };
dbase.collection("site").insertOne(myobj, function(err, res) {
if (err) throw err;
console.log("文档插入成功");
db.close();
});
//查询数据
//指定条件数据
var whereStr = {"name":'菜鸟教程'}; // 查询条件
dbo.collection("site"). find(whereStr).toArray(function(err, result) { // 返回集合中所有数据
if (err) throw err;
console.log(result);
db.close();
});
// 更新一条数据
// 如果要更新所有符合条的文档数据可以使用 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();
});
//删除一条数据
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数据库的登录注册系统
st=>start: 开始
e1=>end: 进入页面
op1=>operation: 登录
op2=>operation: 登录成功
op3=>operation: 登录失败
op4=>operation: 注册
op5=>operation: 注册成功
op6=>operation: 注册失败
cond1=>condition: 数据库是否存在该用户
cond2=>condition: 数据库是否存在该用户
st->op1->cond1
cond1(yes)->op2->e1
cond1(no)->op3->op4->cond2->cond2(no)->op5
cond2(yes)->op6->op4
node.js与redis的互联互通
- Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种
语言的API。 - Redis 与其他 key - value 缓存产品有以下三个特点:
- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
- Redis支持数据的备份,即master-slave模式的数据备份
- 优势
- 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性[4]的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过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 - 数据类型
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
以上资料均来自网上
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数据库
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数据库
var redisPool = redis.createClient(6379, '127.0.0.1', {});
// 数据库的密码
redisPool.auth('123456');
// 共用16个数据库
redisPool.select(1, function () {
console.log('选择数据库第2个数据库');
});
redisPool.on('connect', function () {
console.log('Redis连接成功.');
})
var io = socketio(server);
io.on('connection', function (socket) {
console.log('socketio已连接成功');
// 后续的操作都这里进行
})
- 连接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监听订阅者在客户端订阅一个channel
socket.on('subscribe', function (channel, username) {
//这里我们把用户每次订阅的channel放到了一个set中
credis.sadd('user:' + username, channel);
// 给前端发送消息
socket.emit('message', {});
subscribe.subscribe(channel);
})
- 前端
// 订阅
var socket.emit('subscribe', channel, username);
// 接受消息
socket.on('message', function (message) {
})
取消订阅
- 后台
//scoket监听订阅者在客户端取消订阅一个channel
socket.on('unsubscribe', function (channel, username) {
socket.emit('message', {});
subscribe.unsubscribe(channel);
})
- 前端
socket.emit('subscribe', channel, username);
发布消息
//消息发布者,即publish客户端,无需独占链接
var publish = redis.createClient();
publish.auth('123456');
// 当前发布者向某一个channel中发布消息,
publish.publish(channel, data);
//发布者在某个channel发送消息的时候,订阅频道的redis链接监听这个消息和该频道
subscribe.on('message', function (channel, message, pattern) {
socket.emit('message', {})
})
redis作为缓存对消息的存储和查询
根据5种数据类型有不同的存储和查询方法:
- 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);
});
- 升级方案(优化)
- 增加了群发和点对点发送(以名字为唯一标识符)
- 页面的优化
- 对已订阅的客户端定时发送消息,需要socketio连接的外面执行
setInterval(function () {
publishs.publish('订阅者', '发布的消息');
}, 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无所不能:细数十个令人惊讶的NodeJS开源项目 .TechTarget[引用日期2015-10-31] ↩
-
分布式文档存储数据库 MongoDB .开源社区网[引用日期2012-09-08] ↩
-
什么是原子性,什么是原子性操作?
举个例子:
A想要从自己的帐户中转1000块钱到B的帐户里。那个从A开始转帐,到转帐结束的这一个过程,称之为一个事务。在这个事务里,要做如下操作:
1.. 从A的帐户中减去1000块钱。如果A的帐户原来有3000块钱,现在就变成2000块钱了。
2.. 在B的帐户里加1000块钱。如果B的帐户如果原来有2000块钱,现在则变成3000块钱了。
如果在A的帐户已经减去了1000块钱的时候,忽然发生了意外,比如停电什么的,导致转帐事务意外终止了,而此时B的帐户里还没有增加1000块钱。那么,我们称这个操作失败了,要进行回滚。回滚就是回到事务开始之前的状态,也就是回到A的帐户还没减1000块的状态,B的帐户的原来的状态。此时A的帐户仍然有3000块,B的帐户仍然有2000块。
我们把这种要么一起成功(A帐户成功减少1000,同时B帐户成功增加1000),要么一起失败(A帐户回到原来状态,B帐户也回到原来状态)的操作叫原子性操作。
如果把一个事务可看作是一个程序,它要么完整的被执行,要么完全不执行。这种特性就叫原子性。 ↩