我是PHP的新手,也是Propel的新手。
正如我所读到的,Propel有一个实例池,可以重用查询。
例如
<?php
// first call
$author1 = AuthorQuery::create()->getByFooField('foo');
$foo = $author1->getId();
// SELECT query
...
// second call
$author2 = AuthorQuery::create()->getByFooField('Foo');
// Skips the SQL query and returns the existing $author1 object
$foo = $author2->getId();
事情是
这个物体活了多少时间? 这是因为我必须解析一个excel,并构建一些对象来将它们保存在db中。
所以,也许在excel中我读了100行,我读了25次'foo',所以,每次查询数据库获取PK将是坏事,如果我可以避免24个查询。
看起来Instance Propel解决了这个问题,但我不知道有多少时间。
这取决于时间,使用的内存或执行查询的范围之类的内容? (我的意思是,也许在执行第一个查询的方法之后,实例池被清除,因此,除非第二个查询使用相同的方法,否则它将再次查询数据库。或者可能在对象存活时,我不知道知道)
我搜索了一下但没有发现任何东西,mi直觉告诉我这取决于使用的记忆,但是,没有任何正式的。
或许有更好的方法可以做到这一点。
答案 0 :(得分:2)
只需在上面的评论中添加一个答案。
基本上,实例池是由主键组织的对象的集合。它是不一个查询缓存,而是一个特定实例。几乎在您请求特定记录时,它将被添加到该类的实例池中。当您再次通过它的主键请求该记录时,Propel将返回缓存的对象而不是命中数据库。每当您发出->find()
Propel 将命中数据库时,无论实例池如何。
在生成的基类中,您可以通过查找findPk
方法并查看它如何使用getInstanceFromPool()
和addInstanceToPool()
来查看此行为。
例如:
$entity1 = EntityQuery::create()->findPk(13); // WILL hit database
$entity2 = EntityQuery::create()->findPk(13); // WILL NOT hit database
// This WILL hit DB, even if there is only 1 record & it is in the instance pool
$entity3 = EntityQuery::create()->findOneByName("Record Thirteen");
// This will also hit the DB EVERY TIME, regardless of the instance pool
// even though it is the same query
$entity4 = EntityQuery::create()->findOneByName("Record Thirteen");
// This will always hit the database, even if the instance is in the pool
$entity5 = EntityQuery::create()->findByUniqueField("Unique Value");
希望这会有所帮助。再次,这不是推测,我已经进入代码并仔细检查了这一点。您可以查看生成的基类和propel/runtime/lib/query/ModelCriteria.php
(特别是find()
方法)以查看其工作原理。