首页 > 解决方案 > 如何使用 Sequelize 在 Express 中创建常见的 CRUD 操作?

问题描述

我想用 Sequelize 在 Express js 中创建常见的 crud 操作。我创建了如下 getAll 函数。

 exports.getAll = (module, res,next) => {   
    module
        .findAndCountAll({
            where: {
                CreatedBy: 1,
                isDeleted: false,
                isActive: true
            },
            offset: 0,
            limit: 10,
        }).then((result) => {
            res.status(200).json({
                message: "data Fetched from database",
                statusCode: 200,
                result: result,
            });
        }).catch((error) => {
            console.log(error);
        });
}

我通过传递模型的名称(例如类别)在控制器函数中调用这个通用函数,如下所示

crudOperations.getAll(category, res);

它工作正常。但是如何为发布数据创建函数?对于发布数据,我想使用 Sequelize 的魔法方法(因为一个用户可以关联多个类别,如下所示)

user.hasMany(category, {
        foreignKey: 'CreatedBy'
    });

例如,我想为用户添加类别,所以我想使用如下魔术方法。

req.user
    .createCategory({
        name: name,
    })

标签: node.jsexpresssequelize.js

解决方案


我正在构建应用程序架构和设计。当我们谈论创建通用方法或服务时,它完全取决于我们正在执行的用例或操作类型。

Sequelize 已经具有执行常见操作的基本方法。以下是我的想法,它可能会为您提供更多帮助。请参考下面的伪代码。

回答 1。

以下是可能对您有所帮助的方法,即您如何组织功能。这是我的基本想法,所以可能会有错误的余地。

BaseModel.helper.js

class BaseModelHelper{
    
    static async find(params){
        const {model, where, attributes, include=[] offset:0, limit: 10} = params;
        objFind = {};
        if(Object.keys(where).length > 0){
            objFind = {...objFind, where}
        }   
        if(attributes.length > 0){
            objFind = {...objFind, attributes}
        }  
        if(include.length > 0){
            objFind = {...objFind, include}
        }
        model.find({
            where: where,
            attributes: attributes,
            include,
            offset,
            limit
        }).then((data)=>{
            return data;
        }).catch((err)=>{
            throw new Error(err);
        });
    }

    static async create(params){
        const {model, properties} = params;
        model.create(properties)
        .then((data)=>{
            return data;
        }).catch((err)=>{
            throw new Error(err);
        });
    }


    static async update(params){
        const {model, newData, where} = params;
        model.update(newData, {
            where
        })
        .then((data)=>{
            return data;
        }).catch((err)=>{
            throw new Error(err);
        });
    }

    static async delete(params){
        const {model, where} = params;
        model.destroy(where)
        .then((data)=>{
            return data > 0 ? true : false;
        }).catch((err)=>{
            throw new Error(err);
        });
    }

}

module.exports = BaseModelHelper;

数据服务.js

const BaseModelHelper = require("BaseModel.helper.js);

class DataServices{    

    static async add(){
        // Owner table entry
        const {id} = await BaseModelHelper.create({
            model: "Owner'
            properties:{
                name: 'Loren',
                role: 'admin',
            },            
        });
        // Cat table entry
        const {id: petId} = await BaseModelHelper.create({
            model: "Pet'
            properties:{
                owner_id: 'c0eebc45-9c0b',                
                type: 'cat',
            } 
        });
    }


    static async findWithRelations(){
        const arrData = await BaseModelHelper.find({
            model: 'User',
            where: {
                role: 'admin'
            },
            attributes: ['id', 'username', 'age'],
            include: [{
                model: pet,
                through: {
                    attributes: ['createdAt', 'startedAt', 'finishedAt'],
                    where: {completed: true}
                }
            }]
        });
    }


    static async findBelongs(){
        const arrData = await BaseModelHelper.find({
            model: 'User',
            where: {
                role: 'admin'
            },
            attributes: ['id', 'username', 'age']
        });
    }


    static async update(){        
        const arrData = await BaseModelHelper.update({
            Model: 'Pet',
            newData:{
                name: 'lina',
            }
            where: {
                name: 'suzi',
            }
        });
    }

    static async delete(){
        const arrData = await BaseModelHelper.delete({
            Model: 'Pet',
            where: {
                name: 'lina',
            }
        });
    }

    
}

module.exports = DataServices;

我所描述的上述方法有一个好处是,如果您必须设法集中错误处理程序,您就不必在每个地方都进行错误处理。当发生错误时,它会抛出错误并通过集中 Express 的错误处理程序来捕获。

上述常见的数据库操作类是根据我的经验和我们执行操作的频率构建的。我知道存在比我们预期更多的可能性,但是通过这种方法,我建议您可能不会遇到很多障碍。

答案 2。您应该在您的服务级别创建一个完整的合格查询对象。一旦它在服务级别构建,那么只有您将它传递给我们的 BaseModelHelper。

答案 3。同样,您应该在服务级别创建数据对象。如果数据对象是从多个表构建的,那么您首先在服务级别进行封装,然后您应该传递给 BaseModelHelper 方法。

答案 4. 是的,我也赞成。但是你应该记住一件事,那就是总是有改进的余地。如果您希望为每个模块创建一个方法,那么您应该将此 BaseModelHelper 复制到我建议在服务级别继承该文件的其他任何地方。

所有数据库操作对象都在服务级别而不是控制器级别构建。您的数据库服务和对象准备服务可能会有所不同,因此它会提供更清晰的画面。对象准备服务的范围可能包括更多不同的服务。

上面的方法也是我的思考过程,我根据我的经验建议你。同样,还有更多的改进空间,你可能会去创造。


推荐阅读