模型实例
模型实例
表模型是一个ES6
的类,基于该类去创建的一个实例对象就是表模型实例对象,这个对象是映射到数据库表的一行,类似于Entity
这种概念。 本质上模型实例是数据传输对象。
这里定义一个简单的表模型,例如:
const { Sequelize, Model, DataTypes } = require('sequelize')
const sequelize = new Sequelize('postgres://user:pass@142vip.cn:5432/142vip')
/**
* 定义用户表模型
*/
const User = sequelize.define('user', {
name: DataTypes.TEXT,
favoriteColor: {
type: DataTypes.TEXT,
// 默认值
defaultValue: 'green'
},
age: DataTypes.INTEGER,
cash: DataTypes.INTEGER
});
/**
* 将模型结构同步到数据库表中
*/
(async() => {
// 强制同步
await sequelize.sync({ force: true })
})()
创建实例
尽管模型是一个类,不应该直接使用 new
运算符来创建实例。相反,应该使用 build
方法:
const user = User.build({
name: "142vip.cn"
});
// 判断实例是否为User类创建出来
console.log(user instanceof User) // true
console.log(user.name)
上面的代码没有与数据库进行通信、操作,因为 build
方法仅创建一个对象,表示可以映射到数据库的数据。
如果需要将user
实例保存到数据库表中,可以使用save()
函数来实现持久化,例如:
// 将用户信息持久化到数据库表中
await user.save();
从await
用法来看,save
是一种异步方法。实际上,几乎每个 Sequelize
方法都是异步的。 build
是极少数例外之一。
Sequelize
提供了 create
方法,该方法将上述的 build
方法和 save
方法合并为一个方法:
// 创建持久化对象
const user = await User.create({
name: "142vip.cn"
});
// 信息已经写入到数据库中
console.log(user instanceof User); // true
console.log(user.name)
实例记录
将模型实例直接记录到控制台console.log
会产生很多问题。因为 Sequelize
实例具有很多附加条件。 相反,可以使用 .toJSON()
方法(顺便说一句,它会自动保证实例被 JSON.stringify
编辑好).
const user = await User.create({
name: "142vip"
});
// 不建议这样输出
console.log(user);
// 推荐转化为JSON字符串输出
console.log(user.toJSON());
// 当然也推荐序列化后输出
console.log(JSON.stringify(user, null, 4));
注意:JSON.stringify(user, null, 4)
中,三个参数的使用情况。 参考JSON.stringify()的API
当字段未赋值时,内置实例将自动获得默认值:
const user = User.build({
name: "142vip.cn"
});
// favoriteColor字段的默认值为:green
console.log(user.favoriteColor); // "green"
更新实例
如果需要更改实例的某个字段的值,则再次调用 save
将相应地对其进行更新:
const user = await User.create({
name: "142vip.cn"
});
// 当前实例name字段的值
console.log(user.name)
// 实例对象重新赋值
user.name = "微信公众号:储凡";
// 执行save()更新,数据库中的信息才会更新
await user.save();
删除实例
可以通过调用 destroy
来删除实例
// 创建实例
const user = await User.create({
name: "142vip.cn"
});
// 获取实例对象属性
console.log(user.name)
// 删除实例,从数据库中删除数据
await user.destroy();
实例重载
可以通过调用 reload
方法从数据库中重新加载实例:
// 创建实例
const user = await User.create({
name: "142vip.cn"
});
// 获取实例对象属性
console.log(user.name);
// 实例对象重新赋值
user.name = "微信公众号:储凡";
// 实例对象重载,不会执行save()方法更新数据库
await user.reload();
console.log(user.name);
注意:reload() 调用生成一个 SELECT
查询,以从数据库中获取最新数据。
保存部分字段
通过传递一个列名数组,可以定义在调用 save()
时应该保存哪些属性。基于先前定义的对象设置属性时, 例如:当你通过 Web
应用程序的形式获取对象的值,这非常有用。
此外,这在 update
实现中内部使用。 它是这样的:
// 创建实例对象
const user = await User.create({
name: "142vip.cn"
});
// 获取实例属性
console.log(user.name);
// 属性未初始化赋值,则采用默认值
console.log(user.favoriteColor); // "green"
// 实例对象对象重新赋值
user.name = "142vip.cn";
user.favoriteColor = "blue";
// 保存数据,只更新name属性
await user.save({fields: ['name']});
// name属性已更新为Tom
console.log(user.name);
// 显示为 "blue",因为本地对象将其设置为 "blue"
// 在数据库中仍然是 "green",该字段未作更新
console.log(user.favoriteColor); // "blue"
// 实例对象重载后,获取最新的数据库数据
await user.reload();
// 检查到name属性已改为Tom 其他属性未作更改
console.log(user.name);
console.log(user.favoriteColor); // "green"
save()方法说明
save()
方法在内部进行了优化,只更新真正更改的字段。
- 如果不更改任何内容并调用
save()
方法,Sequelize
将知道save()
方法是多余的,并且不执行任何操作, 不会生成任何查询。 - 如果在调用
save()
方法时只有几个属性发生了更改,那么在UPDATE操作时,将只发送这些更改字段,以提高性能
数据递增或递减
为了递增/递减
实例的值而不会遇到并发问题,Sequelize
提供了 increment
和 decrement
实例方法.
increment
递增decrement
递减
// 创建实例对象
const user = await User.create({
name: "142vip.cn",
age: 18
});
// age属性+1
await user.increment('age', {
by: 2
});
注意: 如只增加 1, 你可以省略 by
参数, 只需执行 user.increment('age')
方法。
- 在
PostgreSQL
中, 除非设置了{returning:false}
参数(不然它将是undefined
), 否则incrementResult
将是更新后的user
。 - 在其它数据库方言中,
incrementResult
将会是undefined
。 如果你需要更新的实例, 你需要调用user.reload()
方法
也可以一次递增多个字段:
// 创建实例对象
const user = await User.create({
name: "142vip.cn",
age: 100
});
// 指定字段
await user.increment({
age: 2,
});
// 如果值增加相同的数量,则也可以使用以下其他语法:
await user.increment(['age'], {
by: 2
});
递增、递减的工作原理完全相同。