九-数据库
数据的仓库,用来保存数据,并且可以提供一些安全措施保证数据的安全
一.常规保存方法的缺点
- 可以被复制
- 可以修改
- 可以删除
- 可能会泄露
二.数据库的安全措施
- 必须输入用户名和密码
- 数据可以定期备份
- 删除可以还原
- 通过多重用户管理不同人员对数据库的操纵权限
- 顶级管理员:什么都能干
- DBA: database admin
- 普通程序员: 可能只能查看数据,新增数据
- 顶级管理员:什么都能干
三.SQL语句(数据库编程语言)
增(insert)
- id 可以不设置,会自动生成
- 不会返回数据,只能看到 几条收到影响
insert into 表名 (字段1,字段2...) values(字段1的值,字段2的值...)
-- 插入数据
-- id可以设置,一般不人为设置,可能设置重复
-- insert into hero (id,name,skill,habbit) values(3,"厄加特","锁链","美女");
-- insert into hero (name,skill,habbit) values("艾希","射箭","蛮王");
删(delete)
- 删除时一定 要跟条件,否则全部删掉
- 删除时 检索条件可以给范围 and关键字连接 多个条件
delete from 表名 条件(可选,一定要跟上)
-- 删除数据
-- delete from hero where id = 5;
//删除id等于5的数据
-- and 等同于 &&
-- delete from hero where id >=3 and id <=7;
//从hero那里删除id大于3小于7的数据
-- delete from hero;
//清空hero
改(update)
- 不跟条件,全部修改
- 根据修改的字段格式,可以写1个或者多个
- 修改的字段的类型如果是字符串要加
update 表名 set 字段名 =值1,字段名2=值2 ... 条件(可选,一定要跟上)
-- 修改数据
-- update hero set name="水晶先锋" where id = 15;
//修改hero中id为5的那行name的值
-- update hero set name="剑圣" , skill="发抖" where id = 17;
//修改hero中id为17的那行的name和skill的值
-- update hero set name="蛮王" , skill="5秒真男人",habbit="丢鸡" where id>=18 and id<=22;
//修改hero中id大于18小于22的name,skill,habbit的值
update hero set name="吉格斯";
//将hero中的所有行的name修改为吉格斯
查(select)
select 字段名1,字段名2..form 表名 条件(可选)
-- 查询数据 设置需要查看的表头
-- select id,habbit,name,skill from hero;
-- 获取所有的字段
-- select * from hero;
-- select * from hero where id =2;
-- select * from hero where skill='想去哪就去哪';
四.拓展
1.通配符–>模糊查询
%
为通配符,一般搭配like
关键字使用。
1.1 以什么开头
- 查询所有
字段
以关键字
开头的数据
select * from 表名 where 字段 like '关键字%';
- 例:
-- 查询user表中name以j开头的所有数据
select *from user where name like 'j%';
1.2 以什么结尾
- 查询所有
字段
以关键字
结尾的数据
select * from 表名 where 字段 like '%关键字'';
- 例:
-- 查询user表中name以y结尾的所有数据
select *from user where name like '%y';
#####1.3 包含什么内容
- 查询所有
字段
包含关键字
的数据
select * from 表名 where 字段 like '%关键字%';
- 例:
-- 查询user表中name中包含o的所有数据
select *from user where name like '%o%';
2 并且条件
- 使用and关键字,例:
-- 查询user表中name为jack,并且age为20的数据
select *from user where name='jack' and age='20'
3 或者条件
- 使用or关键字,例
-- 找到user表中age小于10,或者age大于100的数据
select *from user where age < 10 or age > 100;
4 连表查询
- 很多时候同一个页面的数据是从多张表取出
- 例如:如果想展示所有用户的信息以及它下的订单商品,就需要找到两张表的数据联合起来。
- 如图:
我们首先会想到,把两张表一起查,但这样做不会得到正确结果,例:
select *from customer ,horder;
- 结果如图:
这相当于把两表的所有记录都联了一次(这叫交叉连接),如图说明
- 如果要起到左表张三,只跟右表属于张三的记录连接起来,我们需要用
inner join ... on
关键字 - 语法:
select 字段 from 表1 inner join 表2 on 对应关系
- 例:
-- 找到customer和horder双表结合的结果,只把customer中的cId字段和horder表中custormId字段相等的记录组合在一起
select *from customer inner join horder on customer.cId = horder.custormId
- 如果觉得表名太长,可以给表名起别名,例:
select *from customer c inner join horder h on c.cId = h.custormId
5 分页查询
- 有时候某张表里有大量数据,而我们只需要查中间的某几条,因此可以用下面的分页查询语句
select * from 表名 limit 第几条开始,查几条;
- 例:
-- 查询person表里第10条到第20条数据(一共查出来10条)
select * from person limit 10,10;
五.使用第三方模块进行数据库的增删改查
当第一次执行数据库操作时,是可以成功的。这时第二次执行数据库操作,就会报错
Error: Cannot enqueue Handshake after invoking quit.
原因:
这是因为我们在使用.end()方法关掉连接之后,需要重新调用 createConnection重新创建一个连接。
解决方式:
例如下面封装的一个操作数据库的查询跟增加的方法。方法中每次都会首先使用 mysql.createConnection()创建新连接,再去执行数据库操作,而不是直接把它放到最外层。
//导包
const express = require('express')
// const path = require('path')
const multer = require('multer')
const upload = multer({ dest: 'uploads/' })
const mysql = require('mysql')
const cors = require('cors')
//创建服务器
const app = express()
//设置请求头,将数据转成键值对格式
app.use(cors())
app.use(express.static('uploads'))
let connection;
function setConnect() {
//设置与数据库的连接
connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root',
database: 'user'
});
//连接开启
connection.connect();
}
//新增
app.post('/add', upload.single('heroIcon'), function (req, res, next) {
//获取用户请求数据的资源
const { heroName, heroSkill } = req.body;
console.log(heroName, heroSkill);
const heroIcon = `http://127.0.0.1:3000/` + req.file.filename;
console.log(heroIcon);
//设置服务器与数据库的连接
setConnect();
//对数据库进行编辑
connection.query(`insert into hero_recycle(heroName,heroIcon,heroSkill)values("${heroName}","${heroIcon}","${heroSkill}")`, function (error, results) {
if (error == null) {
res.send({
msg: '新增成功',
code: 200
})
} else {
res.send({
msg: '新增失败',
code: 400
})
}
});
//连接开启
connection.end();
})
//删除
app.get('/delete', (req, res) => {
const id = req.query.id;
console.log(id);
//设置服务器与数据库的连接
setConnect();
//对数据库进行编辑
connection.query(`update hero_recycle set isdelete='yes' where id = ${id}`, function (error, results) {
if (error == null) {
res.send({
msg: '删除成功',
code: 200
})
} else {
res.send({
msg: '删除失败',
code: 400
})
}
});
//连接开启
connection.end();
})
//编辑
app.post('/edit', upload.single('heroIcon'), (req, res) => {
//设置服务器与数据库的连接
setConnect();
//获取用户请求数据的资源
const { id, heroName, heroSkill } = req.body;
console.log(id, heroName, heroSkill);
const heroIcon = `http://127.0.0.1:3000/` + req.file.filename;
console.log(heroIcon);
//对数据库进行编辑
connection.query(`update hero_recycle set heroName="${heroName}",heroIcon="${heroIcon}",heroSkill="${heroSkill}" where id = ${id}`, function (error, results) {
if (error == null) {
res.send({
msg: '编辑成功',
code: 200
})
} else {
res.send({
msg: '编辑失败',
code: 400
})
}
});
//连接开启
connection.end();
})
//获取所有英雄
app.get('/list', (req, res) => {
//设置服务器与数据库的连接
setConnect();
//对数据库进行编辑
connection.query(`select heroName,heroIcon,heroSkill from hero_recycle limit 10,30`, function (error, results) {
// console.log(results);
const data = results
if (error == null) {
res.send({
msg: '获取成功',
code: 200,
data
})
} else {
res.send({
msg: '获取失败',
code: 400
})
}
});
//连接开启
connection.end();
})
//根据id查询
app.get('/search', (req, res) => {
//设置服务器与数据库的连接
setConnect();
//获取用户请求数据的资源
const { id } = req.query;
console.log(id);
//对数据库进行编辑
connection.query(`select heroName,heroIcon,heroSkill from hero_recycle where id = '${id}'`, function (error, results) {
if (error == null) {
res.send({
msg: '获取成功',
code: 200,
data: results
})
} else {
res.send({
msg: '获取失败',
code: 400
})
}
});
//连接开启
connection.end();
})
//监听服务器
app.listen(3000, () => {
console.log('success');
})