Sequelize连表查询 根据Sequelize-auto生成的model-init来进行连表查询的3种方式

景永望
2023-12-01

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",

})

//模型定义
//模型定义 u
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'
})
//模型定义 p
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,否则需要。

// 查询

// 方式一

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)

});

// 结果:

// [

//     {
//         "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)

});

// 结果:

// [

//     { "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)

});

// 结果:

// [

//     { "userName": "张三", "prdName": "ipad", "price": 4.99 },

//     { "userName": "张三", "prdName": "iphone", "price": 3.658 },

//     { "userName": "李四", "prdName": "联想笔记本", "price": 9.32 }

// ]

// 加条件的写法:

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条件

// 事务
//启用事务(自动提交)
functiondoit() {

    return sequelize.transaction(function (t) {
        returnuser.create({
            userName: '黄晓明',

            birthDay: '1991-06-23',

            gender: 0
        }, {
            transaction: t

        }).then(result => {
            returnuser.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)

    })

}

// 循环:

const Op = Sequelize.Op;

const Promise = require('bluebird'); functionrecycle() {
    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

            }))

        })
        returnPromise.all(tranArray)

    }).then(result => {
        console.log('result' + result)

    }).catch(err => {
        console.log('err' + err)

    })

}

 类似资料: