文章目录
NodeJS连接MySQL
MySQL介绍以及安装
参考链接
创建一个数据库
用的是sql语句,请参考百度,使用可视化工具一般为Navicat与SQLYog
MySQL常用数据库操作语句
略
NodeJs连接MySQL数据
mysql模块安装
npm init --yes
npm install mysql --save
在数据库中新建一张表并插入4条数据,sql对应语句如下
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`(
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(128),
`city` VARCHAR(255),
sex TINYINT(2)
);
INSERT INTO `user`(`name`, `city`, `sex`) VALUES('zengraoli1', '北京', '0');
INSERT INTO `user`(`name`, `city`, `sex`) VALUES('zengraoli2', '上海', '0');
INSERT INTO `user`(`name`, `city`, `sex`) VALUES('zengraoli3', '广州', '1');
INSERT INTO `user`(`name`, `city`, `sex`) VALUES('zengraoli4', '深圳', '1');
SELECT * FROM `user`;
用模块mysql去操作这个表
var mysql = require('mysql')
//创建连接
var conn = mysql.createConnection({
host:'127.0.0.1',
user:'zengraoli',
password:'123456',
port:'3306',
database:'db_playcontroller' // 需要自己修改对应数据库名
})
//建立连接
conn.connect()
let sql = 'select * from user where name = ? and city = ?'
//执行sql语句
conn.query(sql,['zengraoli3','广州'],(err,result)=>{
if(err) throw err
console.log(result)
})
//关闭连接
conn.end()
显示如下
PS C:\Users\zeng\Desktop\nodejs\nodejs2\5> node .\5-1.js
[ RowDataPacket { id: 3, name: 'zengraoli3', city: '广州', sex: 1 } ]
深度讲解MySQL连接池
频繁的创建、关闭连接会减低系统的性能,提高系统的开销
连接池可以有效的管理理连接,达到连接复用的效果连
连接池的使用
const mysql = require('mysql')
//创建连接池
var pool = mysql.createPool({
connectionLimit: 10, // 连接池最多可以创建连接数
host:'127.0.0.1',
user:'zengraoli',
password:'123456',
port:'3306',
database:'db_playcontroller'
})
var cityArray = ['北京', '上海', '广州', '深圳']
function show(cityArrayIndex) {
pool.getConnection((err, conn) => {
if (err) throw err
let sql = 'select * from user where city = ?'
//执行sql语句
conn.query(sql, [cityArray[cityArrayIndex]], (err, result) => {
conn.release()
if (err) throw err
console.log(result)
if(cityArrayIndex < cityArray.length) {
// cityArrayIndex = cityArrayIndex+1
cityArrayIndex++
show(cityArrayIndex)
}
})
})
}
cityArrayIndex=0
show(cityArrayIndex)
输出如下内容
PS C:\Users\zeng\Desktop\nodejs\nodejs2\5> node .\5-2.js
[ RowDataPacket { id: 1, name: 'zengraoli1', city: '北京', sex: 0 } ]
[ RowDataPacket { id: 2, name: 'zengraoli2', city: '上海', sex: 0 } ]
[ RowDataPacket { id: 3, name: 'zengraoli3', city: '广州', sex: 1 } ]
[ RowDataPacket { id: 4, name: 'zengraoli4', city: '深圳', sex: 1 } ]
[]
结合数据库改造用户列列表接口(增删改查)
新增数据库的配置
新建一个文件夹,存放文件db_config.js,主要是MySQL的连接配置
let dbOption
dbOption = {
connectionLimit: 10,
host:'127.0.0.1',
user:'zengraoli',
password:'123456',
port:'3306',
database:'db_playcontroller'
}
module.exports = dbOption
新增db操作助手
新增文件夹db,存放conn.js,完成sql语句的执行
var mysql = require('mysql')
var dbOption = require('../config/db_config')
//创建连接池
var pool = mysql.createPool(dbOption)
function query(sql,params) {
console.log(params)
return new Promise((resolve, reject) => {
// 获取连接
pool.getConnection((err, conn) => {
if (err){
reject(err)
return
}
//执行sql语句
conn.query(sql, params, (err, result) => {
conn.release()
if (err) {
reject(err)
return
}
resolve(result)
})
})
})
}
process.on('unhandledRejection', (reason, promise) => {
console.log('Unhandled Rejection:', reason)
})
module.exports = query
新增controller完成用户接口
新增文件夹controller,存放user.js,拼接sql语句调用conn.js完成数据库的查询操作
var query = require('../db/conn')
module.exports = {
async getUserList(urlParams){
let {name,city} = urlParams
let sql = 'select * from user where 1=1 '
if(name){
sql += 'and name = ?'
}
if(city){
sql += 'and city = ?'
}
let resultData = await query(sql,[name,city])
return resultData
},
async addUser(userObj){
console.log(userObj);
let {name,city,sex} = userObj
let sql = 'insert into user (name,city,sex) values (?,?,?)'
let resultData = await query(sql,[name,city,sex])
if(resultData){
return {
msg:'新增成功'
}
}else{
return {
msg:'新增失败'
}
}
},
async delectUser(id){
let sql = 'delete from user where id = ?'
let resultData = await query(sql,[id])
if(resultData.affectedRows > 0){
return {
msg:'删除成功'
}
}else{
return {
msg:'删除失败'
}
}
},
async updateUser(id,userObj){
// console.log(id,userObj);
let {name,city,sex} = userObj
let sql = 'update user set name = ?,city = ?,sex = ? where id = ?'
let resultData = await query(sql,[name,city,sex,id])
if(resultData.affectedRows > 0){
return {
msg:'更新成功'
}
}else{
return {
msg:'更新失败'
}
}
}
}
新增路由接口函数,完成路由截获
新增route文件夹,存放index.js,处理app.js转发过来的链接
var url = require('url')
var {getUserList,addUser,delectUser,updateUser} = require('../controller/user')
function handleRequest(req,res) {
let urlObj = url.parse(req.url,true);
if(urlObj.pathname === '/api/getUserList'&&req.method === 'GET'){
let resultData = getUserList(urlObj.query)
return resultData;
}
if(urlObj.pathname === '/api/addUser'&&req.method === 'POST'){
let resultData = addUser(req.body);
console.log(resultData,'index.js')
return resultData;
}
if(urlObj.pathname === '/api/delectUser'&&req.method === 'POST'){
let resultData = delectUser(urlObj.query.id);
return resultData;
}
if(urlObj.pathname === '/api/updateUser'&&req.method === 'POST'){
let resultData = updateUser(urlObj.query.id,req.body);
return resultData;
}
}
module.exports = handleRequest
app.js的内容
新建服务器,转到操作到route中
var http = require('http');
var routerModal = require('./router/index')
var getPostData = (req) => {
return new Promise((resolve, reject) => {
if (req.method !== 'POST') {
resolve({})
return
}
let postData = '';
req.on('data', chunk => {
postData += chunk;
})
req.on('end', () => {
// console.log(postData)
if(postData){
resolve(JSON.parse(postData))
}else{
resolve({})
}
})
})
}
var server = http.createServer((req, res) => {
//设置允许跨域的域名,*代表允许任意域名跨域
res.setHeader("Access-Control-Allow-Origin","http://127.0.0.1:5501");
res.writeHead(200, { 'content-type': 'application/json;charset=UTF-8' })
getPostData(req).then((data) => {
req.body = data
let result = routerModal(req, res);
if (result) {
result.then(resultData =>{
res.end(JSON.stringify(resultData))
})
} else {
res.writeHead(404, { 'content-type': 'text/html' })
res.end('404 not found')
}
})
})
server.listen(3000, () => {
console.log('监听3000端口')
})
测试
测试使用链接如下
- get:http://127.0.0.1:3000/api/getUserList
- post:http://127.0.0.1:3000/api/updateUser?id=3,json内容{“name”:“zengraoli”,“city”:“广州”,“sex”:1}
- post:http://127.0.0.1:3000/api/addUser,json内容{“name”:“zengraoli5”,“city”:“广州5”,“sex”:1}
- post:http://127.0.0.1:3000/api/delectUser?id=5
分布式文件储存数据库MongoDB
MongoDB的介绍及安装
略
玩转MongoDB可视化工具
可视化软件安装地址:https://www.mongodb.com/download-center/compass
连接使用mongodb://127.0.0.1:27017
进入后可以看到如下内容
点开一个集合可以看到
假如设置了密码,请参考官网:
Connection String URI Format
第三方包mongoose的使用
安装mongoose
npm init --yes
npm install mongoose
用mongoose模块连接MongoDB
var mongoose = require('mongoose')
mongoose.connect('mongodb://127.0.0.1:27017/user_test',{
useNewUrlParser: true,
useUnifiedTopology: true
}).then(()=>{
console.log('连接数据库成功')
}).catch(err => {
console.log(err,'连接数据库失败')
})
MongoDB常用数据库操作之创建集合、文档
mongodb不需要显示创建数据库,如果数据库不存在,它会自动创建
创建集合
首先定义集合结果,然后用mongoose.model方法,传入集合名和集合结构,加入文档内容集合才会出来,详细使用参考测试例子
创建文档的两种形式
第一种形式:
用mongoose.model(上面创建集合)的实例,填入key、value,用该示例进行save提交到集合中,详细使用参考测试例子
第二种形式:
用mongoose.model(上面创建集合)的实例,调用其create方法,填入key、value,即可保存到集合中,详细使用参考测试例子
测试例子
var mongoose = require('mongoose')
var schema = mongoose.Schema
// 连接数据库
mongoose.connect('mongodb://127.0.0.1:27017/my_test',{
useNewUrlParser: true,
useUnifiedTopology: true
}).then(()=>{
console.log('连接数据库成功')
}).catch(err => {
console.log(err,'连接数据库失败')
})
// 创建集合结构
var userSchema = new schema({
name:String,
city:String,
sex:Number
})
// 创建集合
const Model = mongoose.model('user',userSchema)
// 创建文档的第一种形式
// 创建文档
const doc = new Model({
name:'eric',
city:'深圳',
sex:2
})
// 将文档插入数据库中
doc.save()
// 创建文档的第二种形式
// 创建文档并把文档插入数据库中
Model.create({
name:'嘻嘻',
city:'广州',
sex:1
},(err,doc) => {
if(err) throw err
console.log(doc)
}
)
MongoDB如何导入文件数据
导入数据命令,示例为user.json
mongoimport -d 数据库名称 -c 集合名称 --file 导入的数据文件路径
mongoimport -d test -c users --file ./user.json
MongoDB常用数据库操作之查询文档
常规查询
Model.find(条件) //根据条件查询文档,条件为空则查询所有文档, 返回数组
Model.findOne(条件) //默认返回当前集合中的第一条文档 返回对象
Model.find({name:'6'}).then(res => {
console.log(res)
})
Model.findOne({name:'2'}).then(res => {
console.log(res)
})
区间查询
{key:{$gt:value,$lt:value}} gt大于 lt小于 gte大于等于 lte小于等于
Model.find({age:{$gte:18,$lte:38}}).then(res => {
console.log(res)
})
模糊查询
{key:正则表达式}
Model.find({city:/上/}).then(res => {
console.log(res)
})
选择要查询的字段
Modal.find().select(arg) //arg为要操作的字段 字段前加上-表示不不查询该字段
Model.find().select('-name').then(res => {
console.log(res)
})
排序
Modal.find().sort(arg) //arg为要操作的字段 字段前加-表示降序排列列
Model.find().sort('-age').then(res => {
console.log(res)
})
跳过多少条数据、限制查询数量
Modal.find().skip(num).limit(num) //skip跳过多少条数据,limit限制查询数量量
Model.find().skip(2).limit(3).then(res => {
console.log(res)
})
测试例子
const mongoose = require('mongoose')
const schema = mongoose.Schema
//连接数据库
mongoose.connect('mongodb://127.0.0.1:27017/test',{
useNewUrlParser: true,
useUnifiedTopology: true
}).then(()=>{
console.log('连接数据库成功')
}).catch(err => {
console.log(err,'连接数据库失败')
})
//创建集合结构
const userSchema = new schema({
name:String,
city:String,
sex:Number,
age:Number
})
//创建集合
const Model = mongoose.model('user',userSchema)
Model.create({
name:'xx',
city:'上海',
sex:1,
age:28
})
Model.find({name:'6'}).then(res => {
console.log(res)
})
Model.findOne({name:'2'}).then(res => {
console.log(res)
})
Model.find({age:{$gte:18,$lte:38}}).then(res => {
console.log(res)
})
Model.find({city:/上/}).then(res => {
console.log(res)
})
Model.find().select('-name').then(res => {
console.log(res)
})
Model.find().sort('-age').then(res => {
console.log(res)
})
Model.find().skip(2).limit(3).then(res => {
console.log(res)
})
MongoDB常用数据库操作之更更新文档
更新单个文档
两种形式可以更新单个文档,第一种形式使用findOneAndUpdate,详细使用参考测试例子
//找到一个文档并更更新,如果查询多个文档,则更新第一个匹配⽂文档 返回值为该文档
// Model.findOneAndUpdate({name:'2'},{city:'深圳'}).then(res => {
// console.log(res)
// })
第二种形式使用updateOne
//更新指定条件文档,如果查询多个文档,则更新第一个匹配文档
// Model.updateOne({name:'2'},{city:'上海'}).then(res => {
// console.log(res)
// })
更新多个文档
updateOne的多个版本,详细使用参考测试例子
// Modal.updateMany(条件,更更新的值) //如果条件为空,则会更更新全部⽂文档
使用例子
const mongoose = require('mongoose')
const schema = mongoose.Schema
//全局配置
mongoose.set('useFindAndModify',false)
//连接数据库
mongoose.connect('mongodb://127.0.0.1:27017/test',{
useNewUrlParser: true,
useUnifiedTopology: true
}).then(()=>{
console.log('连接数据库成功')
}).catch(err => {
console.log(err,'连接数据库失败')
})
//创建集合结构
const userSchema = new schema({
name:String,
city:String,
sex:Number,
age:Number
})
//创建集合
const Model = mongoose.model('user',userSchema)
//找到一个文档并更更新,如果查询多个文档,则更新第一个匹配⽂文档 返回值为该文档
// Model.findOneAndUpdate({name:'2'},{city:'深圳'}).then(res => {
// console.log(res)
// })
//更新指定条件文档,如果查询多个文档,则更新第一个匹配文档
// Model.updateOne({name:'2'},{city:'上海'}).then(res => {
// console.log(res)
// })
// Modal.updateMany(条件,更更新的值) //如果条件为空,则会更更新全部⽂文档
Model.updateMany({name:'2'},{city:"深圳"}).then(res => {
console.log(res)
})
MongoDB常用数据库操作之删除文档
删除单个文档
//找到一个文档并删除,如果查询多个文档,则删除第一个匹配文档,返回值为该文档
Modal.findOneAndDelete(条件)
//删除指定条件文档,如果查询多个⽂文档,则删除第一个匹配文档,返回值是一个成功对象
Modal.delectOne(条件)
删除多个文档
删除满足条件的多条数据
Modal.deleteMany(条件) //如果条件为空,则会删除全部⽂文档
使用例子
const mongoose = require('mongoose')
const schema = mongoose.Schema
mongoose.set('useFindAndModify',false)
//连接数据库
mongoose.connect('mongodb://127.0.0.1:27017/test',{
useNewUrlParser: true,
useUnifiedTopology: true
}).then(()=>{
console.log('连接数据库成功')
}).catch(err => {
console.log(err,'连接数据库失败')
})
//创建集合结构
const userSchema = new schema({
name:String,
city:String,
sex:Number,
age:Number
})
//创建集合
const Model = mongoose.model('user',userSchema)
// Model.findOneAndDelete({name:'xx'}).then(res => {
// console.log(res)
// })
// Model.deleteOne({name:'2'}).then(res => {
// console.log(res)
// })
// 如果city:'北京'的数据有N条,那么全都删除
Model.deleteMany({city:'北京'}).then(res => {
console.log(res)
})
深度讲解MongoDB字段验证
required 验证字段是否为必须输入,值为boolean
name:{
type:String,
required:[true,'该字段为必选字段'],
}
minlength,maxlength 验证字符的值的最小长度和最大长度
name:{
type:String,
required:[true,'该字段为必选字段'],
minlength:[2,'输⼊入值⻓长度⼩小于最⼩小⻓长度'],
maxlength:[6,'输⼊入值⻓长度⼤大于最⼤大⻓长度'],
}
trim 去除字符串串首尾空格,值为boolean
name:{
type:String,
required:[true,'该字段为必选字段'],
minlength:[2,'输⼊入值⻓长度⼩小于最⼩小⻓长度'],
maxlength:[6,'输⼊入值⻓长度⼤大于最⼤大⻓长度'],
trim:true
}
min、max 验证最小最大数字
age:{
type:Number,
min:18,
max:30
},
default 默认值
createTime:{
type:Date,
default:Date.now
},
enum 规定输入的值
hobbies:{
type:String,
enum:{
values:['唱','跳','Rap'],
message:'该值不不在设定的值当中'
}
},
validate 根据自定义条件验证,通过validator函数处理输入值,message为自定义错误信息
validate:{
validator:v => {
//todo 返回布尔值验证输⼊入值是否有效
}
}
score:{
type:Number,
validate:{
validator:v => {
//返回布尔值
return v&&v>0&&v<100
},
message:'不不是有效的分数'
}
}
通过catch获取errors对象,遍历对象从中获取对应字段自定义报错信息
Modal.create().then().catch(error => {
//获取错误信息对象
const errs = error.errors;
//循环错误信息对象
for(var i in errs ){
console.log(err[i].message)
}
})
测试例子
const mongoose = require('mongoose')
const schema = mongoose.Schema
mongoose.set('useFindAndModify',false)
//连接数据库
mongoose.connect('mongodb://localhost/test',{
useNewUrlParser: true,
useUnifiedTopology: true
}).then(()=>{
console.log('连接数据库成功')
}).catch(err => {
console.log(err,'连接数据库失败')
})
//创建集合结构
const userSchema = new schema({
// name:{
// type:String,
// required:[true,'该字段为必选字段'],
// minlength:[2,'输入值长度小于最小长度'],
// maxlength:[6,'输入值长度大于最大长度'],
// trim:true
// },
// age:{
// type:Number,
// min:18,
// max:30
// },
// createTime:{
// type:Date,
// default:Date.now
// },
hobbies:{
type:String,
enum:{
values:['唱','跳','Rap'],
message:'该值不在设定的值当中'
}
},
score:{
type:Number,
validate:{
validator:v => {
//返回布尔值
return v&&v>0&&v<100
},
message:'不是有效的分数'
}
}
})
//创建集合
const Model = mongoose.model('user',userSchema)
Model.create({hobbies:'篮球',score:-1})
.then(res => console.log(res))
.catch(error => {
const errs = error.errors
for(var i in errs){
console.log(errs[i].message)
}
})