根据一个java学node.js新手来带大家看怎么一步步总接学习,有错误欢迎大家指出
一、引用数据库
在我看来这段代码,首先引用一个模块和连接池,Node.js中的模块给我一种相当于Java中的包和类的组合,但更像类,比如下面的这个创建连接池,但是在nodejs中有个比较重要的就是你想要某个文件里的使方法或者对象被别人用必须要暴露出去比如db,这个写用到只需要在某个文件导入这个模块即可
const mysql = require('mysql')
const db = mysql.createPool({
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'test',
})
module.exports = db
二、创建app.js
用express一般创建服务器都需要四步
先导入模快,创建实例对象,然后导入并用那个路由,接着启动服务器并设置端口
然后这个主要说一下中间件,给我一种java中拦截器的感觉,就比如cors和解析表单的中件件给我一个前置拦截的感觉,而错误级别就像异常拦截
// 导入 express
const express = require('express')
// 创建服务器的实例对象
const app = express()
const joi = require('@hapi/joi')
// 导入并配置 cors 中间件
const cors = require('cors')
app.use(cors())
// 配置解析表单数据的中间件,注意:这个中间件,只能解析 application/x-www-form-urlencoded 格式的表单数据
app.use(express.urlencoded({ extended: false }))
// 托管静态资源文件
app.use('/uploads', express.static('./uploads'))
// 一定要在路由之前,封装 res.cc 函数
app.use((req, res, next) => {
// status 默认值为 1,表示失败的情况
// err 的值,可能是一个错误对象,也可能是一个错误的描述字符串
res.cc = function (err, status = 1) {
res.send({
status,
message: err instanceof Error ? err.message : err,
})
}
next()
})
// 一定要在路由之前配置解析 Token 的中间件
const expressJWT = require('express-jwt')
const config = require('./config')
app.use(expressJWT({ secret: config.jwtSecretKey }).unless({ path: [/^\/api/] }))
// 导入并使用用户路由模块
const userRouter = require('./router/user')
app.use('/api', userRouter)
// 导入并使用用户信息的路由模块
const userinfoRouter = require('./router/userinfo')
app.use('/my', userinfoRouter)
// 导入并使用文章分类的路由模块
const artCateRouter = require('./router/artcate')
app.use('/my/article', artCateRouter)
// 导入并使用文章的路由模块
const articleRouter = require('./router/article')
app.use('/my/article', articleRouter)
// 定义错误级别的中间件
app.use((err, req, res, next) => {
// 验证失败导致的错误
if (err instanceof joi.ValidationError) return res.cc(err)
// 身份认证失败后的错误
if (err.name === 'UnauthorizedError') return res.cc('身份认证失败!')
// 未知的错误
res.cc(err)
})
// 启动服务器
app.listen(3007, () => {
console.log('api server running at http://127.0.0.1:3007')
})
三、创建路由
router下的user路由usr.js
const express = require('express')
const router = express.Router()
// 导入用户路由处理函数对应的模块
const user_handler = require('../router_handler/user')
// 1. 导入验证数据的中间件
const expressJoi = require('@escook/express-joi')
// 2. 导入需要的验证规则对象
const { reg_login_schema } = require('../schema/user')
// 注册新用户
router.post('/reguser', expressJoi(reg_login_schema), user_handler.regUser)
// 登录
router.post('/login', expressJoi(reg_login_schema), user_handler.login)
module.exports = router
router_handler下的use.js
// 导入数据库操作模块
const db = require('../db/index')
// 导入 bcryptjs 这个包
const bcrypt = require('bcryptjs')
// 导入生成 Token 的包
const jwt = require('jsonwebtoken')
// 导入全局的配置文件
const config = require('../config')
// 注册新用户的处理函数
exports.regUser = (req, res) => {
// 获取客户端提交到服务器的用户信息
const userinfo = req.body
// 对表单中的数据,进行合法性的校验
// if (!userinfo.username || !userinfo.password) {
// return res.send({ status: 1, message: '用户名或密码不合法!' })
// }
// 定义 SQL 语句,查询用户名是否被占用
const sqlStr = 'select * from ev_users where username=?'
db.query(sqlStr, userinfo.username, (err, results) => {
// 执行 SQL 语句失败
if (err) {
// return res.send({ status: 1, message: err.message })
return res.cc(err)
}
// 判断用户名是否被占用
if (results.length > 0) {
// return res.send({ status: 1, message: '用户名被占用,请更换其他用户名!' })
return res.cc('用户名被占用,请更换其他用户名!')
}
// 调用 bcrypt.hashSync() 对密码进行加密
userinfo.password = bcrypt.hashSync(userinfo.password, 10)
// 定义插入新用户的 SQL 语句
const sql = 'insert into ev_users set ?'
// 调用 db.query() 执行 SQL 语句
db.query(sql, { username: userinfo.username, password: userinfo.password }, (err, results) => {
// 判断 SQL 语句是否执行成功
// if (err) return res.send({ status: 1, message: err.message })
if (err) return res.cc(err)
// 判断影响行数是否为 1
// if (results.affectedRows !== 1) return res.send({ status: 1, message: '注册用户失败,请稍后再试!' })
if (results.affectedRows !== 1) return res.cc('注册用户失败,请稍后再试!')
// 注册用户成功
// res.send({ status: 0, message: '注册成功!' })
res.cc('注册成功!', 0)
})
})
}
// 登录的处理函数
exports.login = (req, res) => {
// 接收表单的数据
const userinfo = req.body
// 定义 SQL 语句
const sql = `select * from ev_users where username=?`
// 执行 SQL 语句,根据用户名查询用户的信息
db.query(sql, userinfo.username, (err, results) => {
// 执行 SQL 语句失败
if (err) return res.cc(err)
// 执行 SQL 语句成功,但是获取到的数据条数不等于 1
if (results.length !== 1) return res.cc('登录失败!')
// TODO:判断密码是否正确
const compareResult = bcrypt.compareSync(userinfo.password, results[0].password)
if (!compareResult) return res.cc('登录失败!')
// TODO:在服务器端生成 Token 的字符串
const user = { ...results[0], password: '', user_pic: '' }
// 对用户的信息进行加密,生成 Token 字符串
const tokenStr = jwt.sign(user, config.jwtSecretKey, { expiresIn: config.expiresIn })
// 调用 res.send() 将 Token 响应给客户端
res.send({
status: 0,
message: '登录成功!',
token: 'Bearer ' + tokenStr,
})
})
}
这里我感触比较比较深的是和路由里面执行的方法和路由里面实际执行的分离开就像,给我controller和service层相似,实际执行的步骤写的service里面。
总结
本文简单介绍了一下本人发现的自学node.js给java中比较相像的点的联系和比较