nodejs入门到实战(二)

文章目录

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字段验证

参考:Schema Validation

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)
        }
    })

全文所涉及的代码下载地址

参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值