zoukankan      html  css  js  c++  java
  • Vue2+Koa2+Typescript前后端框架教程--05Sequelize(ORM)的使用,实现基础的班级增删改查API

    本篇开始分享Node.js后端服务开发中对于数据结构ORM的实现,主要使用的技术栈是:Sequelize。

    上一篇文章中讲到班级管理的数据结构:ID,班级名称,班级编码,班主任ID,使用的数据库是MySQL,通过Sequelize,实现简单的增删改查的API。

    1. MySQL中创建数据库和班级表。

       1.1 创建数据库demo_node

    CREATE DATABASE `demo_node` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;

       1.2 创建班级表t_class

    CREATE TABLE `demo_node`.`t_class` (
      `id` VARCHAR(36) NOT NULL,
      `class_name` VARCHAR(45) NULL,
      `class_code` VARCHAR(20) NULL,
      `head_teacher_id` VARCHAR(45) NULL,
      PRIMARY KEY (`id`))
    COMMENT = '班级表';

    2. 安装Sequelize。

    npm install sequelize -s
    npm install mysql2 -s

    注:Sequelize连接哪种数据库就要安装对应数据库的驱动

    3. src根目录下添加数据库配置文件:db_config.ts

    import { Sequelize } from 'sequelize';
    
    
    const DbSequelize = new Sequelize({
        host: "localhost",//本地:localhost,其他服务器使用ip地址
        dialect: "mysql",//连接数据库类型
        database: "demo_node",//数据库名称
        username: "root",//数据库账户用户名
        password: "123456",//数据库账户密码
        define: {
            timestamps: false,//是否开启时间戳createAt  deleteAt  updateAt    
            underscored: true,//下划线 
            freezeTableName: true, //禁止sequelize修改表名,默认会在表后边添加一个字母`s`表示复数
            paranoid: true //开启假删除
        },
        pool: {
            max: 10,
            min: 0,
            acquire: 30000,
            idle: 10000
        },
        timezone: '+08:00',//时区设置,东八区
    });
    
    export default DbSequelize;

    4. 定义Model:在models文件夹中修改class.ts,定义班级模型。(上一篇使用的是sequelize-typescript,这里没有使用,所以模型定义有所区别,但是思路一致)

    import { Sequelize, DataTypes } from "sequelize";
    import DbSequelize from "../db_config";
    
    //班级模型
    export default DbSequelize.define('ClassModel', {
        id: {
            type: DataTypes.STRING,
            primaryKey: true//设为主键
        },
        className: {
            type: DataTypes.STRING
        },
        classCode: {
            type: DataTypes.STRING
        },
        headTeacherId: {
            type: DataTypes.STRING
        },
    }, {
        tableName: 't_class'//定义对应数据库表名
    });

    5. 定义Service,在services中修改class.ts:

    import ClassModel from '../models/class';
    
    //班级管理服务
    export default class ClassService {
        //获取所有班级
        async findClassList() {
            try {
                return ClassModel.findAll({
                    attributes: ['id', 'className', 'classCode', 'headTeacherId']
                });
            }
            catch (err) {
                throw (err);
            }
        }
    
        //获取单个班级
        async findClassById(classId: string) {
            try {
                return ClassModel.findOne({
                    attributes: ['id', 'className', 'classCode', 'headTeacherId'],
                    where: { id: classId }
                });
            }
            catch (err) {
                throw (err);
            }
        }
    
        //删除班级
        async deleteClass(classId: string) {
            try {
                return await ClassModel.destroy({ where: { id: classId } });
            }
            catch (err) {
                throw (err);
            }
        }
    
    
        //修改班级
        async editClass(classObj: any) {
            try {
                return await ClassModel.update(classObj, { where: { id: classObj.id }, individualHooks: true });
            }
            catch (err) {
                throw (err);
            }
        }
    
        //添加班级
        async addClass(classObj: any) {
            try {
                return await ClassModel.create(classObj);
            }
            catch (err) {
                throw (err);
            }
        }
    } 

    6. 定义Controller,在controllers文件夹中修改班级控制器class.ts:

    import ClassService from '../services/class';
    
    const clsService = new ClassService();
    
    //班级管理控制器
    export default class ClassController {
        //查找所有班级
        static async findClassList(ctx: any) {
            try {
                //调用查询列表服务,获取结果
                let res = await clsService.findClassList();
                ctx.body = {
                    status: 1,//返回码:1操作成功,0操作错误
                    data: {
                        classList: res
                    }
                }
            }
            catch (err) {
                ctx.throw(err.message);
            }
        }
    
        //根据班级id获取班级详细信息
        static async findClassById(ctx: any) {
            try {
                let id = ctx.request.query.id;
                if (!id) {
                    ctx.body = {
                        status: 0
                    }
                    return;
                }
                //调用查询详情服务,获取结果
                let res = await clsService.findClassById(id);
                ctx.body = {
                    status: 1,
                    data: {
                        class: res
                    }
                }
            }
            catch (err) {
                ctx.throw(err.message);
            }
        }
    
        //删除班级
        static async deleteClass(ctx: any) {
            try {
                let id: string = ctx.request.body.id;
                //调用删除服务,获取结果
                let res: any = await clsService.deleteClass(id);
                if (res === 1) {
                    ctx.body = {
                        status: 1
                    }
                }
                else {
                    ctx.body = {
                        status: 0
                    }
                }
            }
            catch (err) {
                ctx.throw(err.message);
            }
        }
    
        //修改班级
        static async editClass(ctx: any) {
            try {
                let obj: any = ctx.request.body;
                //调用修改服务,获取结果
                let res: any = await clsService.editClass(obj);
    
                if (res[0] !== 1) {
                    ctx.body = {
                        status: 0
                    }
                }
                else {
                    ctx.body = {
                        status: 1,
                        data: {
                            classId: res[1][0].id
                        }
                    }
                }
            }
            catch (err) {
                ctx.throw(err.message);
            }
        }
    
        //添加班级
        static async addClass(ctx: any) {
            try {
                let obj: any = ctx.request.body;
                //调用添加服务,获取结果
                let res: any = await clsService.addClass(obj);
    
                if (!res) {
                    ctx.body = {
                        status: 0
                    }
                }
                else {
                    ctx.body = {
                        status: 1,
                        data: {
                            classId: res.id
                        }
                    }
                }
            }
            catch (err) {
                ctx.throw(err.message);
            }
        }
    }

    7. router如上篇一致,如下:

    import KoaRouter from 'koa-router';
    import ClassController from './controllers/class';
    
    const router = new KoaRouter();
    router.post('/api/class/addClass', ClassController.addClass);
    router.post('/api/class/editClass', ClassController.editClass);
    router.post('/api/class/deleteClass', ClassController.deleteClass);
    router.get('/api/class/findClassById', ClassController.findClassById);
    router.get('/api/class/findClassList', ClassController.findClassList);
    
    export default router;

    8.开始测试:

     8.1 安装koa-body: 由于添加修改删除定义为post方法,所以首先要安装koa-body,才能获取到post过来的数据(删除也可以使用get)

    npm install koa-body -s

     8.2 修改app.ts,添加koa-body中间件引用

    const Koa = require('koa');
    import KoaBody from "koa-body";
    
    const app = new Koa();
    
    app.use(KoaBody({
      multipart: true,
      formidable: {
          maxFileSize: 1000 * 1024 * 1024    // 设置上传文件大小最大限制,默认2M
      },
      formLimit: "10mb",
      jsonLimit: "10mb",
      textLimit: "10mb"
    }));
    
    //引入路由
    import router from './router';
    //添加中间件
    app.use(router.routes());
    app.use(router.allowedMethods());
    
    app.use(async (ctx: any) => {
      ctx.body = 'Hello World...Hello LaoLv';
    });
    
    console.log('app server start on port 3000...')
    app.listen(3000);

    8.3 添加班级,使用postman,操作如下:

      数据库表展示如下:

     8.4 更新班级,操作如下:

      

      数据库表展示如下:

      8.5 查询班级,操作如下:

      8.6 删除班级,操作如下:

       数据库表展示如下:

    9. 如上所示,使用sequelize简单实现三层模式对班级的增删改查。文件结构图如上篇一致:

    这样,基础的增删改查数据流向基本完成。后面会对sequelize中复杂查询进行详细分享,敬请期待。

    (文章为老吕原创,转载请注明出处)

     
  • 相关阅读:
    java.util.concurrent学习
    mysql慢查优化总结
    mysql怎么限制某些查询语句的执行?
    数据库操作提交事务如果不关闭,会有什么样的后果?
    apache的500错误是写到哪个文件里面
    apache也可以做负载均衡,跟nignx的区别是什么?
    ajax提交请求为啥url要用这个函数encodeURI
    MySQL性能调优与架构设计读书笔记
    java枚举的作用
    linux的命令
  • 原文地址:https://www.cnblogs.com/laolv4519/p/14243968.html
Copyright © 2011-2022 走看看