NodeJs 基础总结
特点
Node.js 的特点
异步、非阻塞 IO 模型
事件循环
单线程
总结:轻量和高效
Node.js 的性能和效率非常高。
传统的 Java 语言是一个请求开启一个线程,当请求处理完毕后就关闭这个线程。而 Node.js 则完全没有采用这种模型,它本质上就是一个单线程。
你可能会疑问:一个线程如何服务于大量的请求、如何处理高并发的呢?这是因为,Node.js 采用的是异步的、非阻塞的模型。
这里所谓的“单线程”,指的是 Node 的主线程只有一个。为了确保主线程不被阻塞,主线程是用于接收客户端请求。但不会处理具体的任务。而 Node 的背后还有一个线程池,线程池会处理长时间运行的任务(比如 IO 操作、网络操作)。线程池里的任务是通过队列和事件循环的机制来执行。
模块化
Node.js 中只有模块级作用域,两个模块之间的变量、方法,默认是互不冲突,互不影响,这样就导致一个问题:模块 A 要怎样使用模块B中的变量&方法呢?这就需要通过 exports 关键字来实现。
Node.js中,每个模块都有一个 exports 接口对象,我们可以把公共的变量、方法挂载到这个接口对象中,其他的模块才可以使用。
暴露模块
const name = 'hello'
const foo = function (value) {
return value * 2
}
exports.name = name
exports.foo = foo
暴露模块的方式二: module.exports
module.exports用来导出一个默认对象,没有指定对象名。
语法格式:
// 方式一:导出整个 exports 对象
module.exports = value
// 方式二:给 exports 对象添加属性
module.exports.xxx = value
exports 和 module.exports 的区别
最重要的区别:
使用exports时,只能单个设置属性 exports.a = a
使用module.exports时,既单个设置属性 module.exports.a,也可以整个赋值 module.exports = obj。
const module1 = require('./main.js')
const module2 = require('./main')
const module3 = require('Demo/src/main.js')
require()函数的两个作用:
执行导入的模块中的代码。
返回导入模块中的接口对象。
操作 mysql
Node.js 连接 MySQL
(1)安装 mysql 包:
$ npm install mysql
(2)引入 mysql 包:
const mysql = require("mysql");
(3)建立连接:
let mysql = require("mysql");
let options = {
host: "localhost",
user: "root",
password: 'xxx',
database: "test_database",
};
let connection = mysql.createConnection(options);
connection.connect((err) => {
if (err) {
console.log(err);
} else {
console.log("数据库连接成功");
}
});
正常来说,运行程序后,应该会提示数据库连接成功。
如果在运行时提示错误Client does not support authentication protocol requested by server,解决办法如下:(在终端进入 sql 之后,输入如下命令)
# 注意,这里的 'root' 请填你的user账号, 'localhost' 请填 你的 host, 'password' 请填你的密码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
# 然后执行如下命令
flush privileges;
Node.js 增删改查 MySQL
针对下面这张表:

通过 Node.js可以对其进行一些增删改查操作。代码举例如下。
1、查询表
let mysql = require('mysql');
let options = {
host: 'localhost',
user: 'root',
password: 'xxx',
database: 'test_database'
}
let connection = mysql.createConnection(options);
connection.connect((err) => {
if (err) {
console.log(err)
} else {
console.log('数据库连接成功')
}
});
let strSql1 = 'select * from test_student_table';
connection.query(strSql1, (err, result, fields) => {
if (err) {
console.log(err);
} else {
console.log('test_student_table 表查询结果:' + JSON.stringify(result));
console.log('fields:' + JSON.stringify(fields));
}
})
打印结果如下:
test_student_table 表查询结果:
[{"id":1,"name":"test","age":28},{"id":2,"name":"许嵩","age":34},{"id":3,"name":"邓紫棋","age":28}]
fields:[
{"catalog":"def","db":"test_database","table":"test_student_table","orgTable":"test_student_table","name":"id","orgName":"id","charsetNr":63,"length":11,"type":3,"flags":0,"decimals":0,"zeroFill":false,"protocol41":true},
{"catalog":"def","db":"test_database","table":"test_student_table","orgTable":"test_student_table","name":"name","orgName":"name","charsetNr":33,"length":765,"type":253,"flags":0,"decimals":0,"zeroFill":false,"protocol41":true},
{"catalog":"def","db":"test_database","table":"test_student_table","orgTable":"test_student_table","name":"age","orgName":"age","charsetNr":63,"length":11,"type":3,"flags":0,"decimals":0,"zeroFill":false,"protocol41":true}
]
删除表
let strSql2 = 'drop table test2_table';
connection.query(strSql2, (err, result) => {
if (err) {
console.log(err);
} else {
console.log('表删除成功:' + result);
}
});
打印结果:
表删除成功:
OkPacket {
fieldCount: 0,
affectedRows: 0,
insertId: 0,
serverStatus: 2,
warningCount: 0,
message: '',
protocol41: true,
changedRows: 0
}
删除数据库
将上方的sql语句换一下即可:
let strSql3 = 'drop database test_database';
2、新建数据库
let mysql = require('mysql');
let options = {
host: 'localhost',
user: 'root',
password: 'smyhvae001',
}
let connection = mysql.createConnection(options);
connection.connect((err) => {
if (err) {
console.log(err);
} else {
console.log('数据库连接成功')
}
});
const strSql4 = 'create database test_database3';
connection.query(strSql4, (err, result) => {
if (err) {
console.log(err);
} else {
console.log('新建数据库成功:' + JSON.stringify(result));
}
});
打印结果:
数据库连接成功
新建数据库成功:{
"fieldCount":0,"affectedRows":1,"insertId":0,"serverStatus":2,"warningCount":0,"message":"","protocol41":true,"changedRows":0
}
3、新建表
新建表的sql语句举例:
CREATE TABLE `test_table5` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int DEFAULT NULL,
PRIMARY KEY (`id`)
);
如果是在 js 代码中执行上面这样命令的话,要记得把 sql 语句存放在字符串里的同一行。
代码举例如下:
let mysql = require('mysql');
let options = {
host: 'localhost',
user: 'root',
password: 'smyhvae001',
database: 'test_database'
}
let connection = mysql.createConnection(options);
connection.connect((err) => {
if (err) {
console.log(err);
} else {
console.log('数据库连接成功')
}
});
const strSql5 = 'CREATE TABLE `test_table5` (`id` int NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`age` int DEFAULT NULL,PRIMARY KEY (`id`));';
connection.query(strSql5, (err, result) => {
if (err) {
console.log(err);
} else {
console.log('test 新建表成功:' + JSON.stringify(result));
}
})
打印结果:
数据库连接成功
test 新建表成功:
{
"fieldCount":0,"affectedRows":0,"insertId":0,"serverStatus":2,"warningCount":0,"message":"","protocol41":true,"changedRows":0
}
在指定的表中插入数据
在指定的表中插入数据:
const strSql6 = "insert into test_table5 (name, age) values ('test', '28')";
connection.query(strSql6, (err, result) => {
if (err) {
console.log(err);
} else {
console.log('test 在指定的表中插入数据成功:' + JSON.stringify(result));
}
});
打印结果:
test 在指定的表中插入数据成功:
{
"fieldCount":0,"affectedRows":1,"insertId":1,"serverStatus":2,"warningCount":0,"message":"","protocol41":true,"changedRows":0
}
如果插入的数据是变量(比如是用户提交上来的数据),那么,sql 语句可以这样写:
const strSql7 = "insert into test_table5 (name, age) values (?, ?)";
connection.query(strSql7, ['许嵩', '34'], (err, result) => {
if (err) {
console.log(err);
} else {
console.log('test 在指定的表中插入数据成功:' + JSON.stringify(result));
}
});
异步编程
Node 大量采用异步操作(asynchronous operation),即任务不是马上执行,而是插在任务队列的尾部,等到前面的任务运行完后再执行。
异步IO也叫非阻塞IO。例如读文件,传统的语言,基本都是读取完毕才能进行下一步操作。非阻塞就是Node的callback,不会影响下一步操作,等到文件读取完毕,回调函数自动被执行,而不是在等待。
AMD的概念
AMD(Asynchronous Module Definition):异步模块定义。AMD专门用于浏览器端,模块的加载是异步的。
AMD规范:是 RequireJS 在推广过程中对模块化定义的规范化产出。
RequireJS:一个基于AMD规范实现的模块化开发解决方案。
CMD的概念
CMD(Common Module Definition):同步模块定义。CMD专门用于浏览器端,模块的加载是同步的。模块在使用时才会加载执行。
CMD规范:是 SeaJS 在推广过程中对模块化定义的规范化产出。