NodeJS ORM——sequelize

NodeJS ORM框架——sequelize



什么是ORM?

ORM(Object Relational Mapping)对象关系映射,通过ORM框架,可以自动的把程序中的对象和数据库关联。
在这里插入图片描述

ORM的优势:

  • 开发者不用关心数据库,仅需关心对象
  • 可轻易的完成数据库的迁移
  • 无需拼接复杂的sql语句即可完成精确查询

Sequelize

Sequelize 是一个基于 promise 的 Node.js ORM, 目前支持 Postgres, MySQL, MariaDB, SQLite 以及 Microsoft SQL Server. 它具有强大的事务支持, 关联关系, 预读和延迟加载,读取复制等功能。

模型定义和同步

模型是 Sequelize 的本质. 模型是代表数据库中表的抽象. 在 Sequelize 中,它是一个 Model 的扩展类.

  1. 安装:

    npm install sequelize mysql2
    
  2. 连接到数据库

    const { Sequelize } = require('sequelize');
    const sequelize = new Sequelize('database', 'username', 'password', {
      host: 'localhost',
      dialect: /* one of 'mysql' | 'postgres' | 'sqlite' | 'mariadb' | 'mssql' | 'db2' | 'snowflake' | 'oracle' */
    });
    

    可以使用如下代码测试连接,若连接成功,控制台会输出 “数据库连接成功“ :

    sequelize.authenticate()
    .then(() => {
        console.log('数据库连接成功');
    })
    .catch(err => {
        console.error('数据库连接失败:', err);
    });
    
  3. 创建模型(以管理员为例)

    const { DataTypes } = require('sequelize');
    
    const Admin = sequelize.define('Admin', {
        loginId: {
            type: DataTypes.STRING,
            allowNull: false
        },
        loginPwd: {
            type: DataTypes.STRING,
            allowNull: false
        },
        name: {
            type: DataTypes.STRING,
            allowNull: false
        }
    });
    

    模型创建好之后,要告诉 Sequelize 有关数据库中表的一些信息. 但是,如果该表实际上不存在于数据库中,或者具有不同的列,较少的列或任何其他差异时,就需要模型同步。可以通过调用一个异步函数(返回一个Promise)model.sync(options). 通过此调用,Sequelize 将自动对数据库执行 SQL 查询。

  4. 模型同步:

    • User.sync() - 如果表不存在,则创建该表(如果已经存在,则不执行任何操作)
    • User.sync({ force: true }) - 将创建表,如果表已经存在,则将其首先删除
    • User.sync({ alter: true }) - 这将检查数据库中表的当前状态(它具有哪些列,它们的数据类型等),然后在表中进行必要的更改以使其与模型匹配.
    (async function () {
        await Admin.sync({ alter: true });
        console.log('Admin表同步完成');
    })();
    

    执行该代码,同步完成后,mySql数据库中会看到对应的Admins表:
    在这里插入图片描述
    若不想表中出现 createAt 和 update列,可以在定义表的时候,在第三个参数中设置:

    const Admin = sequelize.define('Admin', {
        loginId: {
            type: DataTypes.STRING,
            allowNull: false
        },
        loginPwd: {
            type: DataTypes.STRING,
            allowNull: false
        },
        name: {
            type: DataTypes.STRING,
            allowNull: false
        }
    }, {
        createdAt: false,
        updatedAt: false
    });
    

模型的增、删、改

  1. 新增
  • 方法一,可以使用build,build 方法仅创建一个对象,该对象 表示 可以 映射到数据库的数据. 为了将这个实例真正保存(即持久保存)在数据库中,应使用 save 方法:

    const ins = Admin.build({
        loginId: 'abc',
        loginPwd: '123456'
    }); // 同步方法,构建一个模型实例
    ins.save().then(() => {
        console.log('新增成功');
    })
    
  • 方法二 create,Sequelize提供了 create 方法,该方法将上述的 build 方法和 save 方法合并为一个方法:

    Admin.create({
        loginId: 'abc2',
        loginPwd: '123456'
    }).then((ins) => {
        console.log('新增成功', ins);
    })
    

可以看到ins:
在这里插入图片描述
2. 删除

  • 方法一,适用于已经得到模型实例的情况,若没有得到模型实例,需要先获取

        // 1.得到实例
        const ins = await Admin.findByPk(adminId);
        // 2.调用实例的destroy方法
        await ins.destroy();
    
  • 方法二,直接调用模型的destory方法,适用于没有得到模型实例的情况:

    	await Admin.destroy({
            where: {
                id: adminId
            }
        });
    
  1. 修改
  • 方法一:如果你更改实例的某个字段的值,则再次调用 save 将相应地对其进行更新,

    // 1.得到实例
        const ins = await Admin.findByPk(id);
        // 2.更新
        ins.loginId = adminObj.loginId;
        ins.loginPwd = adminObj.loginPwd;
        // 可以使用 set 方法一次更新多个字段:
        // ins.set(adminObj);
        // 3.保存
        await ins.save();
    

此处的 save() 也将保留在此实例上所做的任何其他更改, 而不仅仅是之前的 set 调用中的更改.如果要更新一组特定的字段, 可以使用update。

  • 方法二:

    	await Admin.update(adminObj, {
            where: {
                id: id
            }
        });
    

模型查询(常用方法)

  1. findByPk 方法使用提供的主键从表中仅获得一个条目:

    const result = await Admin.findByPk(id);
    if (result) {
        return result.toJSON();
    }
    return null;
    
  2. findOne方法获得它找到的第一个条目(它可以满足提供的可选查询参数).

    async function (loginId, loginPwd) {
        const result = await Admin.findOne({
            where: {
                loginId,
                loginPwd
            }
        });
        // 区分大小写, js判断
        if (result && result.loginId === loginId && result.loginPwd === loginPwd) {
            return result.toJSON();
        }
        return null;
    }
    
  3. findAndCountAll 方法是结合了 findAll 和 count 的便捷方法. 在处理与分页有关的查询时非常有用,在分页中,你想检索带有 limit 和 offset 的数据,但又需要知道与查询匹配的记录总数.

    	exports.getStudents = async function (
    	    page = 1,
    	    limit = 10
    	) {
    	    const where = {};
    	    if (sex !== -1) {
    	        where.sex = !!sex;
    	    }
    	    if (name) {
    	        where.name = {
    	            [Op.like]: `%${name}%`, //模糊查询
    	        }
    	    }
    	    const result = await Student.findAndCountAll({
    	        where,
    	        attributes: ["id", "name", "birthday", "sex"],
    	        offset: (page - 1) * limit,
    	        limit: +limit
    	    })
    	    return {
    	        total: result.count,
    	        datas: JSON.parse(JSON.stringify(result.rows))
    	    };
    

    上面的方法也可以用 findAll 和 count 来实现:

    exports.getStudents = async function (
        page = 1,
        limit = 10,
    ) {
        const result = await Student.findAll({
            offset: (page - 1) * limit,
            limit: +limit
        })
        const total = await Student.count();
        const datas = ç
        return {
            total,
            datas
        }
    }
    
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值