node:ORM、数据模型、脚本创建模型与服务层

插一句:若要删除node_modules下的所有依赖,或者为了要跟换版本而删除所有依赖,命令如下:
rm -rf node_modules\
cnpm i
//package.json
{
"name": "0",
"version": "1.0.0",
"description": "",
"main": "express-run.js",
"scripts": {
"start": "babel-node main.js",
"dev": "cross-env PORT=4000 babel-node main.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"babel-cli": "^6.26.0",
"babel-node": "^0.0.1-security",
"babel-plugin-add-module-exports": "^1.0.2",
"babel-preset-env": "^1.7.0",
"body-parser": "^1.19.0",
"cross-env": "^7.0.2",
"express": "^4.17.1",
"mysql2": "^2.1.0",
"sequelize": "^5.21.2",
"winston": "^3.3.2"
}
}
控制层
- 作用:参数验证,控制接口的调用逻辑
- 流程逻辑比喻:(验证参数–查询数据库–写入redis–生成jwt–返回json)
- 若把上面每一步代码代码都写在控制器,代码冗余
服务层
- 数据库的操作抽到服务层
- 生成jwt抽到一个工具箱,其它模块需要直接导入
- 需要导入数据模型,用于操作数据库
MYSQL
- 版本5.7.xx, 安装mysql数据库
- 导入sql脚本 表名 列名(字段名) 字段类型 数据长度 主键(唯一)
- Navicat Premium 使用工具导入sql,先连接到mysql,创建表初始化数据库
SQL
- 只需了解简单增删改查
- 麻烦:需要写sql并把返回数据手动封装成json对象
ORM–sequelize
- object relational mapping 对象—数据库表—映射关系
- 可以通过对象操作数据库,返回的数据也自动封装成对象
- 生成数据模型----与表字段对应的一个sequelize-json对象
- 使用shell脚本生成数据模型—先连接到数据库—生成
- sequelize-auto:自动生成数据模型对象
- 执行脚本:
sh sequelize-modal.sh不能在win的命令行中运行 - 安装:
cnpm i -S sequelize@5 mysql2
脚本
- 工程自动化中使用的非常多, 作用:一键完成所有工作
- linux—.sh win—.bat java—groovy test—py java—maven/gradle
sequelize-modal.sh脚本文件:
#!/bin/bash
HOST="127.0.0.1"
DB="loan"
USER="root"
PASS="root"
PORT="3306"
DIR="./models"
#JSON_DEFINED="."
EXEC="sequelize-auto -o ${DIR} -d ${DB} -h ${HOST} -u ${USER} -p ${PORT} -x ${PASS} -e mysql"
#EXEC="sequelize-auto -o ${DIR} -d ${DB} -h ${HOST} -u ${USER} -p ${PORT} -x ${PASS} -e mysql -a ${JSON_DEFINED}"
#sequelize是node最受欢迎的orm库,普遍使用 Promise. 意味着所有异步调用可以使用 ES2017 async/await 语法.
#sequelize-auto是可以生成sequelize模型的一个工具
#npm install -g sequelize-auto mysql
#-h 数据库的IP地址
#-d 数据库名
#-u 用户名
#-x 密码
#-p 端口
#-t 表名
#-e 数据库类型
#-a json定义文件路径,可以追加一些自定义配置,如{"timestamps": false}
#sequelize-auto -o . -h localhost -d jindu_loan -u root -x root -p 3306
#run
$EXEC
config.js文件:
//配置文件
const config = {
//配置环境变量 若有环境变量则使用 否则使用默认的
port: process.env.PORT || 3000,
//数据库配置
db: {
database: "loan",
username: "root",
password: "root",
host: "localhost",
port: 3306,
timezone: "+08:00", //时区
dialect: "mysql", //方言
define: {
timestamps: false
}
}
}
export default config
数据库----excel表格(类比)
用工具把sql脚本导入excel中 让excel有表头及初始数据
数据模型----数据表 与excel一一对应的数据表格
服务层需要调用数据模型操作数据(增删改查)
生成模型的文件哪里来的,手写的还是安装的?—在sql定义的
脚本生成的模板文件在下图箭头所指文件夹:

在models文件夹下自写index.js文件导出所有模板文件:
//目录根文件
//将所有的数据模型文件都导出
import fs from 'fs' //node文件系统模块
import path from 'path' //node文件路径模块
import Sequelize from 'sequelize' //三方
import config from '../../config/config' //相对路径--本地
import logger from '../util/logger'
const db = {};
const con = config.db;
let sequelize; //连接数据库
try {
//连接db
sequelize = new Sequelize(con.database, con.username, con.password, con);
logger.info("数据库连接成功")
}catch(e){
logger.error("数据库连接失败")
throw e;
}
//找到数据模型文件,以jd_开头的, 排除index.js
fs.readdirSync(__dirname) //__dirname当前目录
.filter(f => {
return f !== 'index.js'
})
.forEach(f => {
//通过sequelize将模型文件导入 f--绝对路径
console.log(f)
const model = sequelize.import(path.join(__dirname, f))
db[model.name] = model; // db.jd_user = model
})
module.exports = db;
增加服务层(查询数据库放在服务层)

user.service.js文件:
// 用户服务层
import models from '../models' // ./models等价于./models/index
const User = models.jd_user;
export function findUser(account, pwd) {
return User.findOne({
where: {
account: account, //左边的名字对应user模型名 右边是参数
password: pwd
}
}) //findOne--User模型自带的
}
user.ctrl.js文件:(测试findUser方法)
//用户控制器 操作用户的接口
import logger from '../util/logger'
import * as userService from '../service/user.service'
const operations = {
//用户查询
query: function(req, res){
logger.info("用户查询开始")
userService.findUser("admin", "admin@123")
.then(data=> {
res.status(200).json(data)
logger.info("用户查询结束")
})
},
// 用户登录接口
login: function(req, res){
logger.info("调用用户登录接口开始"+JSON.stringify(req.body))
//......
let msg = {msg:"登录成功"}
res.status(200).json(msg)
logger.info("调用登录结束")
},
// 用户查询列表接口
list: function(req, res){//req--request res-response
logger.info("调用用户查询接口")
let users = [{name:"小张"}, {name:"小王"}]
//给浏览器返回数据
// res.status(200).send(users)
res.status(200).json(users)
logger.info("调用用户查询接口结束")
}
}
export default operations
my.route.js添加query接口:
//路由
import express from 'express'
import userCtrl from '../controllers/user.ctrl'
const router = express.Router(); //使用express框架自带的路由 类比vue-router
export default function(app){
//控制器接口--需要路由 接口请求方式(get post)
//接口定义请求方式: get post delete put
//用户 路由地址 请求方式 控制器接口
router.route('/user/query').get(userCtrl.query);
router.route('/user/list').get(userCtrl.list);
router.route('/user/login').post(userCtrl.login);// /api/user/login
//权限
//合同
//把路由配置在myexpress实例上
app.use('/api', router);
}
本文介绍了如何使用Sequelize进行ORM操作,包括脚本自动生成数据模型,以及如何在Node.js中分离控制层与服务层,提升代码复用和数据库操作的灵活性。内容涵盖了MySQL配置、SQL基础、Sequelize的使用以及服务层的重构示例。
1023

被折叠的 条评论
为什么被折叠?



