• Nodejs ORM框架Sequelize(模型,关联表,事务,循环,及常见问题)


    1.建立连接

    const Sequelize = require('sequelize');
    const sequelize = new Sequelize('database', 'username', 'password', {
        host: 'host',
        port: 'port',
        pool: {
            max: 50,
            min: 0,
            //建立连接最长时间
            acquire: 30000,
            //空闲最长连接时间
            idle: 10000
        },
        //默认输出执行sql语句
        logging: console.log,
        define: {
            //默认创建表有 createAt, updateAt
            timestamps: false,
            //可以给表设置别名
            freezeTableName: true,
            // 字段以下划线(_)来分割(默认是驼峰命名风格)
            underscored: false
        },
        //sequelize v4 必须设置方言
        dialect: 'mysql',
        //默认DECIMAL and NEWDECIMAL 返回 String
        dialectOptions: {
            decimalNumbers: true
        },
        //设置别名,否则不识别$like等关键词($like: Op.like对应关系)
        operatorsAliases: 'object',
        //时间上的统一
        timezone: "+08:00",
    })
    

    2.模型定义

    const DataTypes = Sequelize.DataTypes;
    const user = sequelize.define('u', {
        userId: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        userName: {
            type: DataTypes.STRING,
            allowNull: true
        },
        birthDay: {
            type: 'TIMESTAMP',
            allowNull: false
        },
        gender: {
            type: DataTypes.INTEGER,
            allowNull: true,
            defaultValue: 0
        },
        ctime: {
            type: 'TIMESTAMP',
            allowNull: false,
            defaultValue: Sequelize.literal('CURRENT_TIMESTAMP')
        },
        updatedAt: {
            type: 'TIMESTAMP',
            defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
            field: 'ctime'
        }
    }, {
            tableName: 'user'
        })
    
    const products = sequelize.define('p', {
        prdId: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        prdName: {
            type: DataTypes.STRING,
            allowNull: false
        },
        userId: {
            type: DataTypes.INTEGER,
            allowNull: false
        },
        price: {
            type: DataTypes.DECIMAL(5, 4),
            allowNull: false
        }
    })
    products.belongsTo(user, { foreignKey: 'userId', targetKey: 'userId', as: 'u' });
    

    注意点:
    1. type如果不存在则直接用字符串表示 如:’TIMESTAMP’;
    2. 如果需要在更新表字段时记录更新时间,可应使用updateAt,并设置默认值和对应的字段名。
    3. 如果默认值不是具体的数值,可以用literal函数去表示。
    4. tableName 表名, u为别名。
    5. 建立关联关系时,如果外键关联的是主键则不用写targetKey,否则需要。

    3.查询数据

    products.findAll({
        attributes: ['prdName', 'price'],
        include: [{
            model: user,
            as: 'u',
            attributes: ['userName']
        }],
        //raw:true
    }).then(result => {
        console.log(JSON.stringify(result))
    }).catch(err => {
        console.log(err)
    })
    

    //结果1:

    [
        {
            "prdName": "ipad",
            "price": 4.99,
            "u": { "userName": "张三" }
        },
        {
            "prdName": "iphone",
            "price": 3.658,
            "u": { "userName": "张三" }
        },
        {
            "prdName": "联想笔记本",
            "price": 9.32,
            "u": { "userName": "李四" }
        }
    ]
    

    我们换个写法

    products.findAll({
        attributes: ['prdName', 'price'],
        include: [{
            model: user,
            as: 'u',
            attributes: ['userName']
        }],
        raw:true
    }).then(result => {
        console.log(JSON.stringify(result))
    }).catch(err => {
        console.log(err)
    })
    

    结果2

    [
        {
            "prdName":"ipad",
            "price":4.99,
            "u.userName":"张三"
        },
        {
            "prdName":"iphone",
            "price":3.658,
            "u.userName":"张三"
        },
        {
            "prdName":"联想笔记本",
            "price":9.32,
            "u.userName":"李四"
        }
    ]
    

    换个写法

    products.findAll({
        attributes: [Sequelize.col('u.userName'),'prdName', 'price'],
        include: [{
            model: user,
            as: 'u',
            attributes: []
        }],
        raw:true
    }).then(result => {
        console.log(JSON.stringify(result))
    }).catch(err => {
        console.log(err)
    })
    

    结果3:

    [
        {
            "userName":"张三",
            "prdName":"ipad",
            "price":4.99
        },
        {
            "userName":"张三",
            "prdName":"iphone",
            "price":3.658
        },
        {
            "userName":"李四",
            "prdName":"联想笔记本",
            "price":9.32
        }
    ]
    

    可以看出来结果3是我们想要的结果

    加条件的写法:

    products.findAll({
        attributes: [Sequelize.col('u.userName'), 'prdName', 'price'],
        include: [{
            model: user,
            as: 'u',
            attributes: []
        }],
        where: {
            prdName: 'ipad',
            '$u.userId$': 1
        },
        raw: true
    }).then(result => {
        console.log(JSON.stringify(result))
    }).catch(err => {
        console.log(err)
    })
    

    对应sql:

    SELECT `u`.`userName`, `p`.`prdName`, `p`.`price` FROM `products` AS `p` LEFT OUTER JOIN `user` AS `u` ON `p`.`userId` = `u`.`userId` WHERE `p`.`prdName` = ‘ipad’ AND `u`.`userId` = 1;
    
    如果给include 表加where条件 须使用'$u.userId$'这种写法;也可在include加where条件
    

    4.事务

    function doit() {
        //启用事务(自动提交)
        return sequelize.transaction(function (t) {
            return user.create({
                userName: '黄晓明',
                birthDay: '1991-06-23',
                gender: 0
            }, {
                    transaction: t
                }).then(result => {
                    return user.update({
                        userName: '李四',
                    }, {
                            where: { userId: result.userId },
                            transaction: t  //注意(事务transaction 须和where同级)second parameter is "options", so transaction must be in it
                        })
                })
        }).then(result => {
            // Transaction 会自动提交
            // result 是事务回调中使用promise链中执行结果
            // console.log(result.length)
            console.log("ok")
        }).catch(err => {
            // Transaction 会自动回滚
            // err 是事务回调中使用promise链中的异常结果
            console.log(err)
        })
    }
    

    5. 循环

    const Op = Sequelize.Op;
    const Promise = require('bluebird');
    function recycle() {
        let tranArray = [];
        products.findAll({
            attributes: ['prdId', 'prdName', 'userId', 'price'],
            raw: true
        }).then(result => {
            result.forEach(rec => {
                tranArray.push(products.create({
                    prdName: rec.prdName,
                    userId: rec.userId,
                    price: rec.price
                }))
            })
            return Promise.all(tranArray)
        }).then(result => {
            console.log('result' + result)
        }).catch(err => {
            console.log('err' + err)
        })
    }
    

    一般配合事务使用。

  • 相关阅读:
    Getting started with the Web ADF
    将搜狗浏览器设置为IIS的默认浏览器
    What is installed with the Web ADF?
    如何修改Flex的默认浏览器
    What is the Web Application Developer Framework
    windows C++获得本地IP地址
    lua table函数库
    【铸铁】C++服务器面试题.doc
    VC2008下提示找不到MSVCP90D.dll的解决办法
    排序
  • 原文地址:https://www.cnblogs.com/ysk123/p/10222162.html
Copyright © 2020-2023  润新知