Nodejs全栈入门

350 阅读2分钟

npm init -y 快速生成package.json文件

第一个node.js程序:

const os=require('os');
const cpus=os.cpus() //获取当前系统cpu的数量
console.log(cpus.length)//获取内存信息
const tatal=os.totalmem() //bytes
console.log(tatal/1024/1024/1024) //GB
//获取可用内存
const free=os.freemem() //bytes
console.log(free/1024/1024/1024) //GB

const http=require('http');
const server=http.createServer((req,resp)=>{  
 resp.end('hsdggell01 rwrt');
});
server.listen(3001,'127.0.0.1',()=>{ 
 console.log('server启动成功1')
})

nodemon自动重启工具

安装nodemon:

npm install -g nodemon

在package.json文件中配置启动命令:

 "scripts": {   
   "start": "nodemon src/a.js", 
 },

新建nodemon.json文件监测某个范围的文件变动从而自动重启服务:

{ 
 "watch":["./src/"] 
}

express搭建一个web应用

express安装:

npm install express --save

const express = require('express')
const app = express()
const port = 3000

// http://127.0.0.1:3000/name
app.get('/name/:age', (req, resq) => { //接口get传参   
  let {age}=req.params;  
  resq.json({   
    name:'张三', 
    age 
  })  
  resq.send('dfj') 
})
app.listen(port, () => console.log(`Example app listening on port ${port}!`))


express路由演示

// 通过请求的方法类型来区分路由 get/post/put/delete
app.put('/demo', (req, resq) => {    
  resq.json({   
    name:'put请求' 
  })
})
app.post('/demo', (req, resq) => {    
  resq.json({ 
    name:'post请求' 
  })
}) 

//通过uri区分路由
app.get('/demo/byname', (req, resq) => {    
 let {name}=req.query 
  resq.json({  
    name  
  })
}) 
app.get('/demo/byid', (req, resq) => {    
 let {id}=req.query 
 resq.json({  
   id 
 })
}) 



express路由API的使用

// 定义一个 API/路由 客户端无论用什么请求方式都可以得到相应
app.all('/demo', (req, resq) => {    //或 app.use('/demo',(req,resp)=>{})
  resq.json({   
    method:req.method 
  })
}) 

//无论客户端使用任何uri,服务都可以响应 ,例如:日志
app.all('*', (req, resq) => {  //或 app.use((req,resp)=>{})
   resq.json({  
     uri:req.path
   })
}) 



路由的拆分 express.Router

新建2个路由相同的文件,但响应的数据不同

const express=require('express')
const router=express.Router()
router.get('/list',(req,resp)=>{  
 resp.json({    
  list:[  
    {name:'张三'},    // {id:123},    
    {name:'李四'},     // {sex:'male'},   
   ]  
  })
})
module.exports=router

在入口文件中注册路由,用注册路由的前缀来区分相同的路由

const memberRouter=require('./member.router')
const skuRouter=require('./sku.router')

app.use('/member',memberRouter) //注册路由 member/list
app.use('/sku',skuRouter)        //        sku/list


中间件

中间件完整的结构

  1. 是一个函数
  2. err,res,resp,next-->function

function midware(err,req,resp,next){
 //异常  
 //处理业务功能,然后转交控制权 --next()  
 //响应请求-——》结束响应——》当作路由的处理函数
}

function valid_name_midware(req,resp,next){ //验证name参数  
let {name}=req.query;  
if(!name||!name.length){    
   resp.json({     
     message:'缺少name参数!'  
   }) 
 }else{   
    next()  //往下执行
 }}
app.all('*',valid_name_midware)  
const memberRouter=require('./member.router')
const skuRouter=require('./sku.router')
app.use('/member',memberRouter) //注册路由 member/list
app.use('/sku',skuRouter)      //          sku/list


  1. app级别

//放在代码顶端
function app_midware(req,resp,next){
  console.log('app/应用级别的中间件')
  next();}
app.use(app_midware);
//加载一个static中间件
app.use(express.static('static',{   
  extensions:['html','htm'] //默认文件后缀
}))

2.router级别

const router=express.Router()//router级别的中间件
//第一个场景

router.use((req,resp,next)=>{   
  console.log('router中间件') 
  next()
})

function valid_name_midware(req,resp,next){ //验证name参数  
  let {name}=req.query;  
  if(!name||!name.length){    
    resp.json({     
      message:'缺少name参数!'  
    }) 
  }else{
    req.formdata={ //通过req或resp传递参数     
     name   
    }    
    next() 
 }}
 //第二个场景在路由内部使用
 router.get('/list',[valid_name_midware,/*第三方中间件 */],(req,resp)=>{ //也可以跟第三方中间件,如文件上传
   let {formdata}=req //接收中间件的参数 
   resp.json({
    formdata,
    list:[    
     {name:'张三'},    
     {name:'李四'},  
    ]  
  })
})


异常处理

router.get('/list',(req,resp)=>{  throw new Error('异常处理')})


  1. express内置异常处理

//异常处理要放在入口文件所有路由的最后面
function error_middleware(err,req,resp,next){  
 if(err){    
   let {message}=err    
   resp.status(500).json({      
   message:`${message}||'服务异常!'`,//对前端友好的可视化异常   
  }) 
}}
app.use(error_middleware);

2.404异常处理

//404异常处理,异常处理要放在所有路由的最后面
function notFind_middleware(req,resp,next){ //在express中404不属于错误,所以没有err参数  
 resp.json({    
   message:'API不存在' 
 })}
app.use(notFind_middleware);

3.自定义异常处理

function demo_midware(req,resp,next){  
  try{    
    // mysql操作
  } catch(error){   
    next(error) //如果有异常会传递到下面的中间件的err参数中 
}}

sequlize的集成和使用

Sequelize是用于Postgres,MySQL,MariaDB,SQLite和Microsoft SQL Server的基于承诺的Node.js ORM。它具有可靠的事务支持,关系,急切和延迟加载,读取复制等功能。
  • 什么是ORM:

Object-Relational-Mapper,对象关系模型,把数据库中的表和模型相关联,只需操作模型对象。

安装:

npm install --save sequelize

安装CLI:

npm install --save sequelize-cli

初始化项目:

npx sequelize-cli init

这将创建以下文件夹

  • config,包含配置文件,该文件告诉CLI如何与数据库连接
  • models,包含您项目的所有模型
  • migrations,包含所有迁移文件
  • seeders,包含所有种子文件
打开默认配置文件config/config.json,设置连接数据库的参数:

  "development": {   
 "username": "root", 
   "password": "123",
    "database": "sq_db",  
  "host": "127.0.0.1", 
   "dialect": "mysql" 
 },

创建一个模型/迁移

npx sequelize-cli model:generate --name User --attributes firstName:string,lastName:string,email:string

  • name,型号名称
  • attributes,模型属性列表

安装数据库驱动:

npm install --save mysql2

运行迁移,在数据库中实际创建该表,需要运行db:migrate命令

npx sequelize-cli db:migrate

模型用法

  • 写入数据

const models=require('../models')  //引入模型app.get('/creat',async (req,resp,next)=>{    let {firstName,lastName,email}=req.query;    let user=await models.User.create({firstName,lastName,email});//user是promise对象 在表中创建一条数据    resp.json({      user    })})



  • 查询列表

app.get('/list',async (res,resp,next)=>{  
let list=await models.User.findAll(); 
 resp.json({    list  })
})

app.get('/detail/:firstName',async (res,resp)=>{  
let {firstName}=res.params; 
 let user=await models.User.findOne({    
where:{      firstName    }  }); 
 resp.json({    user  })
})