- 什么是关系型数据库
- 如何进行数据表的增删改查
- 使用mysql模块操作对数据表进行增删改查
- 什么是模块化
- 封装db模块
1. 添加数据
格式: insert into 表名(字段名1,字段名2,....) values(值1,值2,....)
注意: ==字段的顺序要和值的顺序是完全匹配的==
==自增长类型的主键,可以使用null来填充;MySQL会自动填充数据==
==如果每个字段都有数据,那么表名后面可以不跟字段名,但是values里面的顺序必须正确==
案例: 向student表中添加一条数据
2. 修改数据
格式:
update 表名 set 字段1=值1, 字段2=值2,... where 修改条件
修改表中的哪一条(几条)数据的 字段1=值1...
案例: 将学号为6的学生姓名改为彦,性别改为女
3. 删除数据
格式: delete from 表名 where 删除条件
案例: 删除学号为4的学生信息
delete from student where sgender="男"
4. mysql模块
4.1 mysql模块的作用
mysql模块是一个第三方模块,专门用来操作MySQL数据库。 可以执行增删改查操作。
npm i mysql
4.2 mysql基本用法
在Node中使用MySQL模块一共需要5个步骤:
加载 MySQL 模块
创建 MySQL 链接对象
链接 MySQL 服务器
执行SQL语句
关闭链接
//1. 加载 MySQL 模块
const mysql = require('mysql')
//2. 创建 MySQL 链接
const conn = mysql.createConntion({
host: '127.0.0.1', // MySQL服务器地址
user: 'root', // 用户名
password: 'root', // 用户名对应的密码
database: 'study', // 要使用的数据库
port: 3306 // MySQL服务器端口号,3006可不写
})
//3. 链接 MySQL 服务器
conn.connect();
//4. 执行SQL语句
//参数1: 要执行的SQL语句
//参数2: SQL语句中的参数,可选参数
//参数3: SQL执行完成后触发的回调函数,有两个参数
// 参数1: 错误对象
// 参数2: SQL执行结果
conn.query(sql, (err, result) => {
//处理错误或者执行结果
})
//5. 关闭链接
conn.end()
4.3 查询 --- read
==执行查询类型的SQL语句,查询结果(result)是一个数组,每个单元是对象,对象的属性是数据表的字段名==
// 目标:使用mysql模块,从student表中查询出所有学生信息
// 并显示到终端
//1. 加载mysql模块
const mysql = require('mysql');
//2. 创建mysql链接对象
const conn = mysql.createConnection({
host: '127.0.0.1', //指定MySQL服务器的地址
user: 'root', //MySQL服务器的用户名
password: 'root', //用户名对应的密码
database: 'study', //指定要使用的数据库
port: 3306 //指定MySQL服务器的端口,如果默认端口可以不写
});
//3. 链接数据库
conn.connect();
//4. 执行SQL语句
const sql = "select * from student";
/**
* 功能: 执行SQL语句
* 参数1: 要执行的SQL语句
* 参数2: 当SQL语句中有占位符时,使用该参数来设置占位符,可选
* 参数3: SQL语句执行完成后触发的回调函数,有三个参数
* err: 如果SQL执行失败则err中保存错误对象信息,成功则为null
* result: SQL语句的执行结果
* fields: 执行本次SQL语句,涉及到的字段信息,一般不用
*/
//当执行查询的SQL语句时,result中以数组形式记录了查询结果。
//数组中每个单元都是一个对象,并且下标是 数据表的字段名
conn.query(sql, (err, result, fields) => {
console.log(err); //错误对象
console.log(result); //SQL执行结果
console.log(fields);
})
//关闭链接
conn.end();
执行结果:
占位符模式:
当SQL语句中使用了占位符,则query方法需要使用参数2
//目标: 查询语句中的占位符
//1. 加载mysql模块
const mysql = require('mysql');
//2. 创建mysql链接对象
const conn = mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'study'
})
//3. 链接数据库
conn.connect();
//4. 执行SQL语句
//查询所有女性学生信息
//在SQL语句中的 ? 就是占位符
const sql = "select * from student where sgender=?";
conn.query(sql, '女', (err, result) => {
if (err) {
return console.log(err);
}
result.forEach(function (item, index) {
console.log(item);
})
})
//5. 关闭链接
conn.end();
4.4 添加 --- create
==执行添加类型的SQL语句,查询结果(result)是一个对象,该对象中有两个属性需要记住==
- affectedRows: 受影响行数
- insertID: 查询数据的主键值
//目标: 向student表中添加一条数据
//1. 加载mysql模块
const mysql = require('mysql');
//2. 创建mysql链接对象
const conn = mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'study'
})
//3. 链接数据库
conn.connect();
//4. 执行SQL语句
const sql = `insert into student
values(null, '阿托', 'atuo', 9000, '男', '2019-02-18', 1)`;
//当执行添加时,result是一个对象,该对象中包含了两个关键属性
// affectedRows: 受影响行数
// insertID: 新添加好的数据的主键值
//
conn.query(sql, (err, result) => {
if (err) {
return console.log(err);
}
console.log(result);
})
//5. 关闭链接
conn.end();
执行结果:
占位符形式:
数据添加时,占位符需要一个对象。 对象的属性是数据表字段名,值是要写入数据表的数据
//目标: 向student表中添加一条数据
//1. 加载mysql模块
const mysql = require('mysql');
//2. 创建mysql链接对象
const conn = mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'study'
})
//3. 链接数据库
conn.connect();
//4. 执行SQL语句
const sql = `insert into student set ?`;
//添加数据时使用站位符,该占位符需要使用一个对象来填充
// 该对象的下标必须是 数据表的字段名
// 带自增长的主键可以不用设置,因为系统会自动设置
const student_data = {
sname: '蕾娜',
snickname: 'lena',
sage: 1000,
sgender: '女',
stime: '2019-02-18',
sdept: 2
}
conn.query(sql, student_data, (err, result) => {
if (err) {
return console.log(err);
}
console.log(result);
})
//5. 关闭链接
conn.end();
4.5 修改 --- update
==执行修改类型的SQL语句,查询结果(result)是一个对象,该对象中有 affectedRows 属性==
//目标: 将刘闯的昵称改为lc,年龄改为30
//1. 加载mysql模块
const mysql = require('mysql');
//2. 创建mysql链接对象
const conn = mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'study'
})
//3. 链接数据库
conn.connect();
//4. 执行SQL语句
const sql = "update student set snickname='lc',sage=30 where sno=5";
conn.query(sql, (err, result) => {
if (err) {
return console.log(err);
}
console.log(result);
})
//5. 关闭链接
conn.end();
占位符模式:
数据修改通常需要两个占位符。 占位符1是要修改的数据,对象形式,属性是数据表字段;占位符2是修改条件,通常是主键值
//目标: 将刘闯的昵称改为lc,年龄改为30
//1. 加载mysql模块
const mysql = require('mysql');
//2. 创建mysql链接对象
const conn = mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'study'
})
//3. 链接数据库
conn.connect();
//占位符模式:
const sql = "update student set ? where sno=?";
//set之后的? 是要修改的实际数据,必须是一个对象形式
const obj = {
snickname: 'chuangzi',
sage:28
}
const sno = 5;
//当一个sql语句中有多个占位符时,参数2需要使用数组形式
//程序解析时,会按照数组的顺序将数据填充到对应占位符的位置
conn.query(sql, [obj, sno], (err, result) => {
if (err) {
return console.log(err);
}
console.log(result);
})
//5. 关闭链接
conn.end();
4.6 删除 --- delete
==执行删除类型的SQL语句,查询结果(result)是一个对象,该对象中有 affectedRows 属性==
//目标: 删除student表中sno=8的数据
//1. 加载mysql模块
const mysql = require('mysql');
//2. 创建mysql链接对象
const conn = mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'study'
})
//3. 链接数据库
conn.connect();
//4. 执行SQL语句
const sql = 'delete from student where sno=8';
conn.query(sql, (err, result) => {
if (err) {
return console.log(err);
}
console.log(result);
})
//5. 关闭连接
conn.end();
占位符模式:
//目标: 删除student表中sno=8的数据
//1. 加载mysql模块
const mysql = require('mysql');
//2. 创建mysql链接对象
const conn = mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'study'
})
//3. 链接数据库
conn.connect();
//4. 执行SQL语句
const sql = 'delete from student where sno=?';
conn.query(sql, 8, (err, result) => {
if (err) {
return console.log(err);
}
console.log(result);
})
//5. 关闭连接
conn.end();
5. Node中的模块化
5.1 什么是模块化
- js设计之初只是为了实现表单验证这样的简单功能,没设计模块化方案,所以js天生不支持模块化
- 不支持模块化简单来说就是在一个js文件内不能引入其他js文件
- 为了让js支持模块化,一些大神自己编写底层库文件,让js开始支持模块化
- js模块化规范有四种标准: AMD CMD CommonJS ES6
- Node属于CommonJS标准
- 使用模块化可以很好的解决变量、函数名冲突问题,也能灵活的解决文件依赖问题
5.2 全局作用域和局部作用域
局部作用域(模块的作用域):
- 一个js文件就是一个模块
- 在一个js文件中定义的属性(变量、常量)和方法默认都只能在当前js文件中使用
案例: 创建index.js、user.js两个模块。 user.js 模块中定义属性和方法,index.js导入user.js模块
- 创建 users.js 文件
- 创建index.js文件,加载 users.js
执行结果:
全局作用域:
- 在js文件中声明的属性和方法如果都挂载到global对象下;当其他js文件导入该模块后,就能使用该模块下的属性和方法了。
案例: 创建index.js、game.js两个模块。 game.js 模块中定义属性和方法并挂载到global对象下,index.js导入game.js模块
- 创建 game.js 文件,并将数据挂载到 global对象下
- 在 index.js 文件中加载 game.js 文件
测试结果:
5.3 module.exports导出属性和方法
- 将变量、对象、函数等挂载到global对象上并不推荐,因为容易造成变量污染。
- 推荐使用 module.exports 导出模块中定义好的变量、对象、方法
- 使用require加载(导入)模块后,就能使用模块中定义好的变量、对象、方法了
案例: users.js中定义变量、对象、方法,最后使用 module.exports 导出
index.js中加载users.js模块
访问结果:
5.4 封装 db.js 模块
核心思想: mysql操作流程是固定的,尤其是前三步。将前三部封装到一个模块,导出链接对象。 链接对象就可以调用query方法执行sql语句,也能执行end方法关闭链接
5.5 改造留言板列表页
模板:留言板中动态显示的数据要从 cmt 表中读出并显示在页面上
核心思路:
加载db.js模块,再调用query方法执行查询 (select * from cmt),当查询结果正确时,调用render方法渲染页面
- 使用express搭建服务器,监听 /index 路由,将页面正常显示出来
四步流程:
-
调用 mysql 模块从study.cmt表中查询数据
image.png
- 调用 res.render方法渲染数据
① 加载 express-art-template 模板引擎 并进行配置
② 修改 index.html 模板页面,使用 each 循环输出数据
③ 调用 res.render方法