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

本文介绍了如何使用Sequelize进行ORM操作,包括脚本自动生成数据模型,以及如何在Node.js中分离控制层与服务层,提升代码复用和数据库操作的灵活性。内容涵盖了MySQL配置、SQL基础、Sequelize的使用以及服务层的重构示例。

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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值