node基础学习--sequelize

柴琦
2023-12-01

1、查找器

findAll()
findByPk()
findOne()
findOrCreate()
findAndCountAll()
findAndCountAll 方法是结合了 findAll 和 count 的便捷方法. 在处理与分页有关的查询时非常有用,在分页中,你想检索带有 limit 和 offset 的数据,但又需要知道与查询匹配的记录总数.
findAndCountAll 方法返回一个具有两个属性的对象:
(1)count - 一个整数 - 符合查询条件的记录总数
(2)rows - 一个数组对象 - 获得的记录

const { count, rows } = await Project.findAndCountAll({
  where: {
    title: {
      [Op.like]: 'foo%'
    }
  },
  offset: 10,
  limit: 2
});
console.log(count);
console.log(rows);

2、原始查询

默认情况下,函数将返回两个参数 - 一个结果数组,以及一个包含元数据(例如受影响的行数等)的对象
const [results, metadata] = await sequelize.query("UPDATE users SET y = 42 WHERE x = 12");
// 结果将是一个空数组,元数据将包含受影响的行数.

在不需要访问元数据的情况下,你可以传递一个查询类型来告诉后续如何格式化结果.

const { QueryTypes } = require('sequelize');
const users = await sequelize.query("SELECT * FROM `users`", { type: QueryTypes.SELECT });

其他类型

enum QueryTypes {
  SELECT = 'SELECT',
  INSERT = 'INSERT',
  UPDATE = 'UPDATE',
  BULKUPDATE = 'BULKUPDATE',
  BULKDELETE = 'BULKDELETE',
  DELETE = 'DELETE',
  UPSERT = 'UPSERT',
  VERSION = 'VERSION',
  SHOWTABLES = 'SHOWTABLES',
  SHOWINDEXES = 'SHOWINDEXES',
  DESCRIBE = 'DESCRIBE',
  RAW = 'RAW',
  FOREIGNKEYS = 'FOREIGNKEYS',
  SHOWCONSTRAINTS = 'SHOWCONSTRAINTS'
}

3、关联

Sequelize 提供了 四种 关联类型,并将它们组合起来以创建关联:

HasOne 关联类型
BelongsTo 关联类型
HasMany 关联类型
BelongsToMany 关联类型

A.hasOne(B); // A 有一个 B
A.belongsTo(B); // A 属于 B
A.hasMany(B); // A 有多个 B
A.belongsToMany(B, { through: 'C' }); // A 属于多个 B , 通过联结表 C

它们都接受一个对象作为第二个参数(前三个参数是可选的,而对于包含 through 属性belongsToMany 是必需的)

A.hasOne(B, { /* 参数 */ });
A.belongsTo(B, { /* 参数 */ });
A.hasMany(B, { /* 参数 */ });
A.belongsToMany(B, { through: 'C', /* 参数 */ });

A.hasOne(B) 关联意味着 A 和 B 之间存在一对一的关系,外键在目标模型(B)中定义.(以b的某个属性进行关联

A.belongsTo(B)关联意味着 A 和 B 之间存在一对一的关系,外键在源模型中定义(A).

A.hasMany(B) 关联意味着 A 和 B 之间存在一对多关系,外键在目标模型(B)中定义.
自定义外键:

// 方法 1
Foo.hasOne(Bar, {
  foreignKey: 'myFooId'
});
Bar.belongsTo(Foo);

// 方法 2
Foo.hasOne(Bar, {
  foreignKey: {
    name: 'myFooId'
  }
});
Bar.belongsTo(Foo);

// 方法 3
Foo.hasOne(Bar);
Bar.belongsTo(Foo, {
  foreignKey: 'myFooId'
});

// 方法 4
Foo.hasOne(Bar);
Bar.belongsTo(Foo, {
  foreignKey: {
    name: 'myFooId'
  }
});
k1.hasMany(k2, { foreignKey: 'event_id' }); 这是include能生效的关键

4、联表查询

    await Cart.findAll({
      attributes: ['id'], include: { attributes: [ 'id' ], model: Goods, include: { attributes: [ 'id' ], model: Spec } } }) 

(1) attributes // 联表的字段
(2)modal // 连接的表

5、条件查询

const { Op } = require('sequelize');
User.findAll({
  where: {
    name: 'abc',	// 默认是等于查询,即Op.eq
    [Op.and]: [{status:1}, {id: 11}],	// and查询
    [Op.or]: [{status:1}, {id: 11}], // or 查询,
    someAttribute: {
    	{[Op.or]: [12, 13]}, // 对一个字段单独用or查询,
      [Op.ne]: 20,	// 不等于
      [Op.is]: null,	// IS NULL
      [Op.not]: true, // IS NOT TRUE
      [Op.gt]: 6, // > 6
      [Op.gte]: 6, // >= 6
      [Op.lt]: 10, // < 10
      [Op.lte]: 10, // <=10
      [Op.between]: [6, 10], // BETWEEN 6 AND 10
      [Op.notBetween]: [11, 15], // NOT BETWEEN 11 AND 15
      [Op.in]: [1, 2], // IN [1,2]
      [1, 2, 3],	// IN的简洁写法
      [Op.notIn]: [1, 2], // NOT IN [1,2]
      [Op.like]: '%hat', // LIKE '%hat',
      [Op.notLike]: '%hat',
      [Op.startsWith]: 'hat', // LIKE 'hat%'
      [Op.endsWith]: 'hat', // LIKE '%hat'
      [Op.substring]: 'hat', // LIKE '%hat%'
      [Op.iLike]: '%hat', // ILIKE '%hat'(大小写不敏感)
      [Op.regexp]: '^[h|a|t]', // REGEXP/~ '^[h|a|t]'
      [Op.notRegexp]: '^[h|a|t]',
      [Op.iRegexp]: '',
      [Op.notIRegexp]: '',
      [Op.any]: [2, 3],	// ANY ARRAY[2, 3], // 仅Postgres
  }
});

https://haofly.net/sequelize/
学习链接:https://cloud.tencent.com/developer/article/1533442
https://blog.csdn.net/weixin_30672295/article/details/95914958
https://github.com/demopark/sequelize-docs-Zh-CN

6、事务

非托管事务
// 首先,我们开始一个事务并将其保存到变量中
const t = await sequelize.transaction();

try {

  // 然后,我们进行一些调用以将此事务作为参数传递:

  const user = await User.create({
    firstName: 'Bart',
    lastName: 'Simpson'
  }, { transaction: t });

  await user.addSibling({
    firstName: 'Lisa',
    lastName: 'Simpson'
  }, { transaction: t });

  // 如果执行到此行,且没有引发任何错误.
  // 我们提交事务.
  await t.commit();

} catch (error) {

  // 如果执行到达此行,则抛出错误.
  // 我们回滚事务.
  await t.rollback();

}
托管事务
try {

  const result = await sequelize.transaction(async (t) => {

    const user = await User.create({
      firstName: 'Abraham',
      lastName: 'Lincoln'
    }, { transaction: t });

    await user.setShooter({
      firstName: 'John',
      lastName: 'Boothe'
    }, { transaction: t });

    return user;

  });

  // 如果执行到此行,则表示事务已成功提交,`result`是事务返回的结果
  // `result` 就是从事务回调中返回的结果(在这种情况下为 `user`)

} catch (error) {

  // 如果执行到此,则发生错误.
  // 该事务已由 Sequelize 自动回滚!

}

7、Sequelize literal()

sequelize.literal()方法用于创建一个字面量对象,该对象(val)会被直接传入所生成的SQL语句中,而不会进行任何转义

批量自增、自减
在Sequelize中要实现:
UPDATE `user` SET `age`=`age` + 1 WHERE `number` > 10;
可以通过Model.update()并借助sequelize中的顶级方法sequelize.literal()来实现:
User.update({age:sequelize.literal('`age` +1')}, {where:{number:{$gt:10}}}).then(function(user){ console.log('success'); })
DISTINCT
在Sequelize中要实现:
SELECT COUNT(DISTINCT `group`) FROM `user` WHERE `number` > 10;
可以通过Model.findAll()并借助sequelize中的顶级方法sequelize.literal()来实现:
User.findAll({where: {number:{$gt:10}}, attributes: [ [sequelize.literal('COUNT(DISTINCT(group))'), 'count'] ]}).then(function(list){ console.log(list[0].count); })
最后通过别名取出count。

学习链接:https://www.dazhuanlan.com/2020/03/14/5e6cecd8422fc/

8、批量添加数据

Model.bulkCreate()

let  updatePhone = [{userName: '李白‘},{userName: '杜甫'}]

db_erroressence.active_telephone.bulkCreate(updatePhone) ;
db_erroressence:链接的数据库, 
active_telephone:表,
bulkCreate 批量添加的方法

sequelize官网:https://sequelize.org/

9、聚合查询sequelize.fn()

Sequelize提供了聚合函数,可以直接对模型进行聚合查询:
aggregate(field, aggregateFunction, [options])-通过指定的聚合函数进行查询
sum(field, [options])-求和
count(field, [options])-统计查询结果数
max(field, [options])-查询最大值
min(field, [options])-查询最小值

Order.findAll({attributes:['name', [sequelize.fn('SUM', sequelize.col('price')), 'sum']], group:'name', having:['COUNT(?)>?', 'name', 1], raw:true}).then(function(result){
console.log(result);
})
select name, SUM(price) from orders GROUP BY name;
// -----------------------------------------------------------------
Order.findAll({attributes:['sum', [sequelize.fn('SUM', sequelize.col('name')), 'sum']], group:'name', raw:true}).then(function(result){
console.log(result);
})

http://www.cppcns.com/wangluo/javascript/173346.html

10、实例

const Sequelize = require('sequelize');
const co = require('co');
const db = new Sequelize('test_db','root','123456wsx',{
    host:'127.0.0.1',
    dialect:'mysql',
    pool:{
        max:5,
        min:0,
        idle:1000  // 如果一个线程 10 秒钟内没有被使用过的话,那么就释放线程
    }
})

const User = db.define('user',{
    id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true,
    },
    userName: {
        type: Sequelize.STRING, // 指定值的类型
        field: 'user_name' // 指定存储在表中的键名称
    },
    // 没有指定 field,表中键名称则与对象键名相同,为 email
    email: {
        type: Sequelize.STRING
    }
},{
    timestamps: true,
    createdAt: 'created_at',
    updatedAt: 'updated_at',
    charset: 'utf8mb4',
    // 如果为 true 则表的名称和 model 相同,即 user
    // 为 false MySQL创建的表名称会是复数 users
    // 如果指定的表名称本就是复数形式则不变
    freezeTableName: false
});

// 创建实例(方法1)
const addUser = function(userName, email) {
    // 向 user 表中插入数据
    return User.create({
        userName: userName,
        email: email
    });
};

// 创建实例(方法2)
function addUser2(userName,email) {
    const user = User.build({userName:userName, email:email});
    user.save();
}

// 更新实例
function updateUser(userName,email) {
    User.update({email: email},{where:{userName:userName}});
}

// 查询一个
function SearchOne(userName,) {
    return co(function* (){
        const search = yield User.findOne({
            where:{
                userName:{
                    [Sequelize.Op.eq]:userName
                }
            }
        });
        console.log(search.dataValues);
    })
}

// 查询列
function searchColumn(userName) {
    return co(function* (){
        const user = yield User.findOne({
            where:{userName: userName},
            attributes:['userName','email']
        });
        console.log(user.dataValues);
    });
}

// 查询所有
function searchAll() {
    return co(function* (){
        const search = yield User.findAll({
            order: [
                ['id', 'desc']
            ]
        });
        console.log(search.map(item => item.dataValues));
    })
}

// 分页查询
const searchPageList = function() {
    return co(function* (){
        const user = yield User.findAll({
            order:[
                ['id','asc']
            ],
            limit:2,
            offset:2
        });
        console.log(user.map(item => item.dataValues))
    })
}

// 查询条数和数据
function SearchAllCount(){
    return co(function* (){
        const { count, rows } = yield User.findAndCountAll({
            where: {
              userName: {
                [Sequelize.Op.like]: '%ya%'
              }
            }
          });
          console.log(count);
          console.log(rows.map(item => item.dataValues));
    })
}

// 原始查询
function OriginSearch() {
    return co(function* (){
        const users = yield db.query("select * from users",{type: Sequelize.QueryTypes.SELECT});
        console.log(users);
    })
}

https://www.sequelize.com.cn/core-concepts/assocs
https://blog.csdn.net/m0_37068028/article/details/103595218
https://blog.csdn.net/m0_37068028/article/details/103595111
https://blog.csdn.net/d649237053/article/details/99623451

 类似资料: