Sequelize.js - 如何正确使用关联的 get 方法(每次调用都没有 sql 查询)?
Sequelize.js - how to properly use get methods from associations (no sql query on each call)?
我正在为 ORM 使用 Sequelize.js 并且有一些关联(现在实际上并不重要)。我的模型从这些关联中获得 get
和 set
方法。像这样(来自文档):
var User = sequelize.define('User', {/* ... */})
var Project = sequelize.define('Project', {/* ... */})
// One-way associations
Project.hasOne(User)
/*
...
Furthermore, Project.prototype will gain the methods getUser and setUser
according to the first parameter passed to define.
*/
所以现在,我有 Project.getUser()
,这 return 是一个承诺。但是如果我在同一个对象上调用它两次,我会得到 SQL 查询执行了两次。
我的问题是 - 我是否遗漏了什么,或者这是预期的行为?我实际上不想每次对该对象调用相同的方法时都进行额外的查询。
如果这是预期的 - 我是否应该将自定义 getter 与我手动填充的成员变量和 return(如果存在)一起使用?或者有什么更聪明的东西? :)
更新
从 DeBuGGeR 的回答来看——我知道我可以在查询时使用 includes
来急切加载所有内容,但我根本不需要它,而且我不能一直这样做。如果我一开始就加载我的整个数据库,只是为了理解(根据某些标准)我不需要它,那是浪费资源和巨大的开销。我想根据情况进行额外的查询。但我也不能破坏我拥有的所有模型(DAO 对象)并创建新的模型,其中包含所有信息。我应该能够更新其中缺失的部分(来自关系)。
如果您使用 getUser() 它将进行查询调用,它不会授予您访问用户的权限。您可以根据关联手动将其保存到 project.user 或 project.users。
不过你可以试试预加载
Project.find({
include: [
{ model: User, as: 'user' } // here you HAVE to specify the same alias as you did in your association
]
}).success(function(project){
project.user // contains the user
});
还有 getUser() 的例子。不要指望它会自动缓存用户并且不要巧妙地覆盖它,因为它会产生副作用。 getUser 应该从数据库中获取,它应该!
Project.getUser().then(function(user){
// user is available and is a sequelize object
project.user = user; // save project.user and use it till u want to
})
事情的第一部分很清楚 - 每次调用get[Association]
(例如Project.getUser()
)WILL 结果查询数据库。
Sequelize 不维护任何类型的状态,也不缓存结果。您可以在调用的 Promisified 结果中获得 user
,但如果您再次需要它 - 您将不得不进行另一个查询。
@DeBuGGeR 所说的 - 关于使用访问器也不是真的 - 访问器仅在查询后 立即出现,并且不会保留。
有时候这样不行,你必须自己实现某种缓存系统。棘手的部分来了:
如果 你想使用相同的获取方法 Project.getUser()
,你将无法做到,因为 Sequelize 覆盖了你的 instanceMethods
。比如你有上面提到的关联,这个就不行:
instanceMethods: {
getUser: function() {
// check if you have it, otherwise make a query
}
}
修复它的可能方法很少 - 稍微更改 Sequelize 核心(首先检查该方法是否存在),或者对这些函数使用某种包装器。
有关此的更多详细信息,请参见此处:https://github.com/sequelize/sequelize/issues/3707
感谢 mickhansen 在如何理解该做什么方面的合作 :)
我正在为 ORM 使用 Sequelize.js 并且有一些关联(现在实际上并不重要)。我的模型从这些关联中获得 get
和 set
方法。像这样(来自文档):
var User = sequelize.define('User', {/* ... */})
var Project = sequelize.define('Project', {/* ... */})
// One-way associations
Project.hasOne(User)
/*
...
Furthermore, Project.prototype will gain the methods getUser and setUser
according to the first parameter passed to define.
*/
所以现在,我有 Project.getUser()
,这 return 是一个承诺。但是如果我在同一个对象上调用它两次,我会得到 SQL 查询执行了两次。
我的问题是 - 我是否遗漏了什么,或者这是预期的行为?我实际上不想每次对该对象调用相同的方法时都进行额外的查询。
如果这是预期的 - 我是否应该将自定义 getter 与我手动填充的成员变量和 return(如果存在)一起使用?或者有什么更聪明的东西? :)
更新
从 DeBuGGeR 的回答来看——我知道我可以在查询时使用 includes
来急切加载所有内容,但我根本不需要它,而且我不能一直这样做。如果我一开始就加载我的整个数据库,只是为了理解(根据某些标准)我不需要它,那是浪费资源和巨大的开销。我想根据情况进行额外的查询。但我也不能破坏我拥有的所有模型(DAO 对象)并创建新的模型,其中包含所有信息。我应该能够更新其中缺失的部分(来自关系)。
如果您使用 getUser() 它将进行查询调用,它不会授予您访问用户的权限。您可以根据关联手动将其保存到 project.user 或 project.users。
不过你可以试试预加载
Project.find({
include: [
{ model: User, as: 'user' } // here you HAVE to specify the same alias as you did in your association
]
}).success(function(project){
project.user // contains the user
});
还有 getUser() 的例子。不要指望它会自动缓存用户并且不要巧妙地覆盖它,因为它会产生副作用。 getUser 应该从数据库中获取,它应该!
Project.getUser().then(function(user){
// user is available and is a sequelize object
project.user = user; // save project.user and use it till u want to
})
事情的第一部分很清楚 - 每次调用get[Association]
(例如Project.getUser()
)WILL 结果查询数据库。
Sequelize 不维护任何类型的状态,也不缓存结果。您可以在调用的 Promisified 结果中获得 user
,但如果您再次需要它 - 您将不得不进行另一个查询。
@DeBuGGeR 所说的 - 关于使用访问器也不是真的 - 访问器仅在查询后 立即出现,并且不会保留。
有时候这样不行,你必须自己实现某种缓存系统。棘手的部分来了:
如果 你想使用相同的获取方法 Project.getUser()
,你将无法做到,因为 Sequelize 覆盖了你的 instanceMethods
。比如你有上面提到的关联,这个就不行:
instanceMethods: {
getUser: function() {
// check if you have it, otherwise make a query
}
}
修复它的可能方法很少 - 稍微更改 Sequelize 核心(首先检查该方法是否存在),或者对这些函数使用某种包装器。
有关此的更多详细信息,请参见此处:https://github.com/sequelize/sequelize/issues/3707
感谢 mickhansen 在如何理解该做什么方面的合作 :)