Sequelize ORM

sequelize

定义:Sequelize是一款基于Nodejs功能强大的异步ORM框架。同时支持PostgreSQL, MySQL, SQLite and MSSQL多种数据库,很适合作为Nodejs后端数据库的存储接口,为快速开发Nodejs应用奠定扎实、安全的基础

连接postgresql

创建连接

const Sequelize = require('sequelize')
const sequelize = new Sequelize('database', 'username', 'password', {
  host: 'localhost',
  dialect: /* 'mysql' | 'mariadb' | 'postgres' | 'mssql' 之一 */,
});
//使用连接池
pool: {
    max: 5,
    min: 0,
    acquire: 30000,	//该池在抛出错误之前将尝试获得连接的最长时间(以毫秒为单位)
    idle: 10000	//连接释放之前可以空闲的最长时间(以毫秒为单位)
  }

定义模型

第一种:使用Sequelize.Model类中的init()

const Model = Sequelize.Model;
class User extends Model {}
User.init({
  // 属性
  firstName: {
    type: Sequelize.STRING,
    allowNull: false
  },
  lastName: {
    type: Sequelize.STRING
    // allowNull 默认为 true
  }
}, {
  sequelize,
  modelName: 'user'
  // 参数
});

第二种:sequelize.define【内部调用了init()】

const User = sequelize.define('user', {
  // 属性
  firstName: {
    type: Sequelize.STRING,
    allowNull: false
  },
  lastName: {
    type: Sequelize.STRING
    // allowNull 默认为 true
  }
}, {
  // 参数
});

将模型与数据库同步

sequelize.sync({
	force: true|false	//当为true时,先删除表后再创建
})

sequelize操作数据库

添加单条记录

animal.create({
    name: '小鸡',
    age: 2
}).then(result => {
    console.log(JSON.stringify(result))
}).catch(err => {
    console.log(err)
})

批量添加

animal.bulkCreate([
  {name: '知了',age:16},
  {name: '羊',age:14}
  ]).then(function (p) {
      console.log('created. ' + JSON.stringify(p));
  }).catch(function (err) {
      console.log('failed: ' + err);
  })

修改数据

animal.update(
    {name:'蚂蚁'},
    {where:{id:[4,8]}}
    ).then(([affectedCount])=>{
        console.log('受影响的数量'+affectedCount)
    }).catch(err=>{
        console.log(err)
    })

删除数据

animal.destroy({
    where: {
    id:{[Op.gt]:35}
    }
}).then(affectedRows => {
    
console.log(affectedRows)
}).catch(err=>{
    console.log(err)
}) 

查询数据

Hooks

Hook(也称为生命周期事件)是执行 sequelize 调用之前和之后调用的函数

添加Hooks的三种方式

第一种方式

class Order extends Model{}
Order.init({
    orderName:DataTypes.STRING,
    remark:{
        type:DataTypes.ENUM,
        values:['好用','美观','便宜']
    }
},{
    hooks:{
         beforeValidate:(order,options)=>{
            order.remark = '好用'
        },
        afterValidate:(order,options)=>{
            order.orderName = '牙刷'
        } 
    },sequelize
})

第二种方式

class Order extends Model{}
Order.init({
    orderName:DataTypes.STRING,
    remark:{
        type:DataTypes.ENUM,
        values:['好用','美观','便宜']
    }
},{
   sequelize
})

Order.addHook('beforeValidate',(order,options)=>{
    order.remark = '好用'
})
Order.addHook('afterValidate','someCustomName',(order,options)=>{
    return Promise.reject(new Error("you can not do that"))
})

第三种方式

class Order extends Model{}
Order.init({
    orderName:DataTypes.STRING,
    password:DataTypes.STRING,
    remark:{
        type:DataTypes.ENUM,
        values:['好用','美观','便宜']
    }
},{
  sequelize
})
Order.beforeCreate((order,options)=>{
    return hashPassword(order.password).then(hashedPw=>{
        order.password = hashedPw
    })
})
Order.afterValidate('myHookAfter',(order,options)=>{
    order.orderName = '毛巾'
})

Removing hooks移除 Hook

只能删除有名称参数的 hook.

Order.addHook('afterValidate','someCustomName',(order,options)=>{
    return Promise.reject(new Error("you can not do that"))
})
Order.removeHook('afterValidate','someCustomName')

Global hooks全局 Hooks

//定义一个全局hook
const sequelize = new Sequelize(..., {
    define: {
        hooks: {
            beforeCreate: () => {
                // 做些什么
            }
        }
    }
});

案例

class User extends Model {}
User.init({}, { sequelize });
class Project extends Model {}
Project.init({}, {
    hooks: {
        beforeCreate: () => {
            // 
        }
    },
    sequelize
});

User.create() // 运行全局 hook
Project.create() // 运行其自身的 hook (因为全局 hook 被覆盖)

Permanent Hooks常驻 Hooks

无论模型是否指定了自己的 beforeCreate hook.本地 hook 总是在全局 hook 之前运行::

//定义一个常驻Hook
sequelize.addHook('beforeCreate', () => {
    // 做些什么
});

案例

class User extends Model {}
User.init({}, { sequelize });
class Project extends Model {}
Project.init({}, {
    hooks: {
        beforeCreate: () => {
            // 做些其它什么
        }
    },
    sequelize
});

User.create() // 运行全局 hook
Project.create() //运行其自己的 hook 之后运行全局 hook

关联

一对一

使用belongsTo或者haveOne,belogsTo是将关联键添加到前者模型中,haveOne相反

//一对一关联
  class Player extends Model {}
  Player.init({/* attributes */}, { sequelize, modelName: 'player' });
  class Team extends Model {}
  Team.init({/* attributes */}, { sequelize, modelName: 'team' });

  Player.belongsTo(Team);
  //Player.hasOne(Team); 

Foreign keys 外键

自定义的外键使用foreignKey,原本默认会将conmpany_id添加到user中,现在就会将fk_company添加到user中。underscored:true字段会用下划线的格式默认使用驼峰原则

class User extends Model {}
User.init({/* attributes */}, { sequelize, modelName: 'user',underscored:true })
class Company extends Model {}
Company.init({/* attributes */}, { sequelize, modelName: 'company' });

User.belongsTo(Company, {foreignKey: 'fk_company'}); 

Target keys 目标键

目标键是源模型上的外键列指向的目标模型上的列. 默认情况下,belongsTo 关系的目标键将是目标模型的主键. 要定义自定义列,使用 targetKey

class User extends Model {}
User.init({
    id:{
        type:Sequelize.INTEGER,
         primaryKey:true,
         unique: true
    }},{ sequelize, modelName: 'user' })
class Company extends Model {}
Company.init({
    name:{
    	type:Sequelize.STRING,
     	unique: true
}},{ sequelize, modelName: 'company' });
User.belongsTo(Company, {foreignKey: 'fk_companyname', targetKey: 'name'}); // 添加 fk_companyname 到 User

Source keys 源键

源关键是源模型中的属性,它是指向目标模型的外键属性. 默认情况下,hasOne关系的源键将是源模型的主要属性. 要使用自定义属性,使用sourceKey.

class User extends Model {}
User.init({/* attributes */}, { sequelize, modelName: 'user' })
class Company extends Model {}
Company.init({/* attributes */}, { sequelize, modelName: 'company' });

// 将 companyName 属性添加到 User
// 使用 Company 的 name 属性作为 source 属性
Company.hasOne(User, {foreignKey: 'companyName', sourceKey: 'name'});

一对多

使用hasMany

//一对多关联
class Person extends Model{}
Person.init({},{sequelize,modelName:'person'})
class Project extends Model{}
Project.init({},{sequelize,modelName:'project'})
//使用as后getPerson()、setPerson()就变成了getWorker()、setWorker()可以使用Project.prototype打印出来
Project.hasMany(Person,{as:'Worders'}) 
//console.log(Project.prototype)//查看project有哪些方法

多对多

使用belongsToMany

案例:会额外创建一个UserProject的表,表中包含了外键userId和projectId

class User extends Model {}
User.init({/* attributes */}, { sequelize, modelName: 'user',underscored:true })
class Project extends Model {}
Project.init({/* attributes */}, { sequelize, modelName: 'Project' });
Project.belongsToMany(User, {through: 'UserProject'});
User.belongsToMany(Project, {through: 'UserProject'});

预加载

当你从数据库检索数据时,也想同时获得与之相关联的查询,这被称为预加载.当你调用 findfindAll 时使用 include 属性.

user.findAll({ include: [ task ] }).then(([user]) => {
    console.log(user.get({
        plain: true
    }))
})

sequelize事务

  • 事务分为两种:
    • 一种需要我们手动执行commitrollback命令进行提交和回滚
    • 另一种是自动管理的,根据promise链的结果自动提交或回滚事物
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值