什么是数据库?
-
数据库即存储数据的仓库,可以将数据进行有序的分门别类的存储,它是独立于软件之外的软件,可以通过API去操作它
-
数据库软件开放了一些api可以在网站程序中通过api去操作数据库中的数据
为什么使用数据库?
-
动态网站的数据都是存储在数据库中
-
数据库可以用来持久存储客户端通过表单收集的用户信息
-
数据库软件本身可以对数据进行高效的管理
常见的数据库软件:MongoDB MySQL Oracle
-
mysql 下载地址:→
-
mysql端口:3306 http协议:8080 https:443
数据库中类型使用:
- varchar表示字符串
- int整数
- bigint 大整数
- double双精度浮点数
- float单精度浮点数
sql 语句:
-
创建库
CREATE DATABASE 库名
-
切换库
USE 库名
-
创建表
CREATE TABLE 表名(字段1,字段2...)
CREATE TABLE 表名( //--字段 类型 修饰 主键primary key 自增 auto_increment u_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '描述信息', u_name VARCHAR(30) NOT NULL UNIQUE KEY, u_sex VARCHAR(20) NOT NULL DEFAULT '默认值', u_createdate DATETIME )
-
插入
INSERT INTO '表名' ('字段1','字段2'...)VALUES (值1,值2...)
-
查看
SELECT * FROM '表名'
SELECT * FROM '表名' WHERE 条件
案例:登陆时要查找符合条件的用户名及密码
SELECT * FROM 表名 WHERE user_name='XX' AND 'user_password'='XX'
sql 语句中的and等价于js中的&&
-
修改数据
UPDATE '表名' SET 字段1=值 WHERE 条件
UPDATE '表名' SET user_name='小8' WHERE 条件
???? 有中文时不成功 -
删除数据 物理删除 及真正的将用户数据删除一般不会这样做
DELETE FROM 表名 WHERE 条件
-
软删除 修改用户状态为禁用状态 设置的有一个字段是控制用户是否可用1
UPDATE '表名' SET user_status=0 WHERE 条件
-
联合查询
SELECT * FROM 表名称 AS 别名a LEFT JOIN 表名称 AS 别名b ON 别名a.字段=别名b.字段 //---这两个字段必须要有逻辑关系
SELECT * FROM `class` as a left JOIN `students` as b ON a.class_id=b.stu_class
SELECT stu_id,stu_name FROM `class` as a left JOIN `students` as b ON a.class_id=b.stu_class
-
删除表
DROP TABLE 表名
-
删除库
DROP DATABASE 库名
-
查询某表中的第2条到第4条记录
SELECT * FROM 表名 LIMIT 开始索引,条数
SELECT * FROM 'student' LIMIT 1,3 (索引从0开始的)
-
新增字段
ALTER TABLE 表名 ADD COLUMN 字段 VARCHAR(50) DEFAULT '默认值' NULL COMMENT '备注信息'
创建 create 库database 表 table 非空 not null 主键 primary key 自增长 auto_increment 默认 default
切换 use 插入
总结:node.js中 列名也就是字段,不要引号,sql语句里的字符串引号只能使用单引号,或双引号
连接数据库
引入mysql(npm官网搜索mysql)
npm i mysql --save–dev
node.js的第三方包的mysql
- 作用:node和mysql数据库链接,进行增删改查的操作
使用:
-
1 :链接数据库
-
前提:保证数据库服务器的开启
-
链接方式:
-
mysql.createConnect({配置信息})
偏向于单次使用的语义
每一次都 链接 操作 关闭
-
mysql.createPool({配置信息})
偏向于链池的语义
链接 操作 操作 操作 操作 … 不关闭一直开着
-
-
-
2: 执行sql语句
使用链接信息 去调用执行sql语句的方法
一个方法 执行不同的sql语句
语法:
-
链接配置.query(sql语句,回调函数) 是异步回调
-
链接配置.query(sql语句,数组,回调函数)
sql语句里面以 问号 的形式留下一些 坑
数组里面的每一项去填补前面留下的坑
-
const mysql=require('mysql');
console.log(mysql)
const db=mysql.createConnection({
host:'localhost',
port:3306,
user:'root',
password:'123457',
database:'userList',
})
let sql='SELECT * FROM `otherUser` WHERE user_id=? AND user_name=?'
let userId=3;
let userName='698';
db.query(sql,[userId,userName],(err,info)=>{
if(err) return console.log('err---',err);
console.log('查询成功了',info)
});
db.end();
首先在nodejs中安装mysql,并显示在依赖中
cnpm install mysql --save;
// 1 引入
const mysql = require('mysql');
// 2 创建链接配置
const conn = mysql.createConnection({
host:'localhost', // 主机名 (服务器地址) 或者127.0.0.1
port:3306; //数据库端口
user:'root', //用户名
password:'123457', // 密码
database:'数据库名字', // 你操做的是数据库中的哪一个库
})
// 3 建立链接
conn.connect()
// 4 生成sql语句 增删改查操作
let sql = '.....';
//--let sql='SELECT * FROM otherUser WHERE user_id=1 AND user_name=8'
//5 执行sql语句
conn.query(sql, (err, result) => {
if(err){
console.log(err);
return
}
// 6 处理结果
console.log(result)
})
//7.结束连接!!!不能一直连着!!
conn.end();
结果result
- 针对select语句, result 是是一个数据集合, 是一个数组,数组中的每个值是一个对象,代表一条记录
- 针对 inert , update, delete 语句, result是一个操作的结果, 通过对其中的字段进行判断,可以知道操作是否成功
OkPacket {
fieldCount: 0,
affectedRows: 1, // 受影响的行数 通过该字段可以判断操作是否成功
insertId: 0,//插入后返回自增的主键ID
serverStatus: 2,
warningCount: 0,
message: '',
protocol41: true,
changedRows: 0 // 改变的函数 执行update 语句时
}
封装MySQL连接
------封装一个db模块
var db = {};
var mysql = require('mysql');
var conn = mysql.createConnection({
host:'localhost', // 主机名 (服务器地址)
user:'root', //用户名
password:'root', // 密码
database:'数据库名字', // 写上自己要连接的数据库名字
});
db.query = function(sql, callback){
if (!sql) {
callback();
return;
}
conn.query(sql, (err, result)=> {
if (err) {
console.log(err);
callback(err, null);
return;
};
callback(null,result);
});
}
module.exports = db;
测试
var db = require('./db.js');
var sql = 'SELECT count(*) as count from user';
db.query(sql, function(err, result){
if (err) {
console.log(err);
return;
}
console.log('用户数量 : ', result[0].count);
});
// 插入一条数据
let insertData = (table,datas,callback)=>{
var fields='';
var values='';
for( var k in datas){
fields+=k+',';
values=values+"'"+datas[k]+"',"
}
//最后一位是逗号。
fields=fields.slice(0,-1);
values=values.slice(0,-1);
console.log(fields,values);
var sql="INSERT INTO "+table+'('+fields+') VALUES('+values+')';
connection.query(sql,callback);
}
// 更新一条数据
let updateData=function(table,sets,where,callback){
var _SETS='';
var _WHERE='';
var keys='';
var values='';
for(var k in sets){
_SETS+=k+"='"+sets[k]+"',";
}
_SETS=_SETS.slice(0,-1);
for(var k2 in where){
_WHERE+= k2+"="+where[k2];
}
var sql="UPDATE "+table+' SET '+_SETS+' WHERE '+_WHERE;
console.log(sql);
connection.query(sql,callback);
}
// 删除一条数据
let deleteData=function(table,where,callback){
var _WHERE='';
for(var k2 in where){
//多个筛选条件使用
_WHERE+= k2+"="+where[k2];
}
var sql="DELETE FROM "+table+' WHERE '+_WHERE;
connection.query(sql,callback);
}
exports.selectAll = selectAll;
exports.insertData = insertData;
exports.deleteData = deleteData;
exports.updateData = updateData;
实现用户的增删改查
查询数据库,实现登录的小案例。
node+mysql 数据库连接池
1. 什么是数据库连接池?
数据库连接池是程序启动时建立足够的数据库连接,并将这些连接组成一个池,由程序动态地对池中的连接进行申请,使用和释放。
2. 使用数据库连接池原理及优点是什么?
数据库连接池在初始化时将会创建一定数量的数据库连接放到连接池中,连接池都将一直保证至少拥有这么多的连接数量,当有数据库需要被连接的时候,它会向数据库连接池申请资源和使用,使用完成后会释放到数据库连接池中。当然数据库连接池中拥有最小连接数量和最大连接数量,当数据库的连接超过连接池中最大的数量的时候,这些请求将被加入到等待队列中。
其实他们的原理就好比我们公司的招聘前端开发一样,当有A项目的时候,我们公司需要招聘一个前端开发去做项目,但是当公司有B、C、D、等项目的时候,或者很多项目的时候需要不断的招聘前端开发,那么这样会给公司带来很多人力成本的。因此我们需要一个前端主管来管理这些前端资源。前端主管手下假如有5个前端开发,那么当A、B、C、D、E、项目来的时候,前端主管会依次把这些项目分配给对应的开发人员去跟进。但是当还有F等项目的时候,因为F项目已经超过前端人员的时候,没有人再去支持这些个项目,因此这些项目需要排期,等A、B、C、D、E 其中任何一个开发完成后,上线了,然后这些开发人员就和数据库一样释放资源,返回到前端组来,然后前端主管再把F项目分配到对应的开发人员。这个比方就好比可以理解为一个数据库连接池了。而不是有n个项目需要招聘n个前端开发来做项目,那这样的缺点是公司的人力成本会大大的增加。所以数据库的链接池也是这个意思,当网站某一天有很大的流量的时候,数据库服务器需要为每次链接创建一次数据库链接。这样就很浪费数据库的资源,并且频繁的创建和关闭数据库的链接,很容易导致服务器内存溢出等情况发生。
连接池的作用是:数据库的连接池负责分配,管理和释放数据库链接的。它允许应用程序重复使用一个现有的数据库的链接。而不是重新创建一个。
3. node + mysql 实现数据库连接池
3.1 安装引入MySQL模块
在命令行安装MySQL
cnpm i mysql -S
在app.js中引入mysql模块
const mysql = require("mysql")
3.2 调用MySQL模块的createPool方法
//创建连接池
const pool = mysql.createPool({
host : 'localhost', //连接主机
port : 3306, //端口号
database : 'test', //连接的是哪一个库
user : 'root', //用户名
password : '', //密码
connectionLimit : 50, //用于指定连接池中最大的链接数,默认属性值为10.
queueLimit:3 //用于指定允许挂起的最大连接数,如果挂起的连接数超过该数值,就会立即抛出一个错误,默认属性值为0.代表不允许被挂起的最大连接数。
})
在建立了连接池之后,可以直接使用连接池对象的getConnection方法从连接池中获取一个连接,如果连接池中没有可用连接,将隐式的建立一个数据库连接。
//err: 该参数是指操作失败时的错误对象。
//connection: 该值为一个对象,代表获取到的连接对象。当连接失败时,该值为undefined。
pool.getConnection(function(err,connection){
if(err){
console.log('与mysql数据库建立连接失败');
pool.releaseConnection();//释放链接
}else{
console.log('与mysql数据库建立连接成功');
connection.query('select * from admin',function(err,rows){
if(err){
console.log('执行sql语句失败,查询数据失败');
connection.release();//释放链接
}else{
//rows为结果
console.log(rows);
//关闭连接池
pool.end();
}
})
}
})
connection.release() 当一个连接不需要使用时,使用该方法将其归还到连接池中 release 释放
connection.destroy() 当一个连接不需要使用且需要从连接池中移除时,可以使用该方法 destory销毁
pool.end() 当一个连接池不需要使用时,可以使用该方法关闭连接池
// ----封装一个用于sql查询的模块
// console.log(module)
const mysql=require('mysql');
const pool=mysql.createPool({
host:'localhost',
port:3306,
user:'root',
password:'123457',
database:'newTable',
});
module.exports.query=(sql,values,callback)=>{
pool.getConnection((err,connection)=>{
//---与链接池创建的链接失败
if(err){
console.log('创建链接失败')
pool.releaseConnection();//释放链接
callback(err,null);//执行回调
}
//-- 与链接池创建的链接成功时返回connetion 链接对象
//-- 链接对象执行sql语句
connection.query(sql,values,(err,res)=>{
if(err){
//---sql语句执行失败 没有找到指定的结果
console.log('sql语句执行失败 没有找到指定的结果')
connection.release(); //释放链接
callback(err,null);//执行回调
}else{
//---sql语句执行成功
connection.release(); //释放链接
callback(null,res);//执行回调
}
})
})
}
----引入模块 调用
--
const query=require('./db').query;
--调用1
let sql='SELECT * FROM class WHERE class_id=? AND class_name=?'
let userId=1;
let userName='喳岈山';
query(sql,[userId,userName],(err,res)=>{
if(err){
console.log('发生了错误1**',err)
return
}
console.log('找到了1',res)
})
--调用2
--创建表
sql=`CREATE TABLE user_list3(u_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '用户id',u_name VARCHAR(30) NOT NULL UNIQUE KEY,u_sex VARCHAR(20) NOT NULL DEFAULT '男',u_createdate DATETIME)`
query(sql,null,(err,res)=>{
if(err){
console.log('发生了错误3*32*',err)
return
}
console.log('找到了%%%2·',res)
})
--向表中新增字段password
query("ALTER TABLE user_list ADD COLUMN passWord VARCHAR(50) DEFAULT '123' NULL COMMENT '备注信息'",null,(err,res)=>{
if(err){
console.log('发生了错误3*32*',err)
return
}
console.log('找到了!!!!·',res)
})