我是 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,并构建一些对象以将它们保存在数据库中。
所以,也许在我读了 100 行的 Excel 中,我读了 25 次“foo”,所以,如果我可以避免 24 次查询,每次查询数据库来获取 PK 将是一件坏事。
看起来 Instance Propel 解决了这个问题,但我不知道解决了多少次。
这取决于时间、使用的内存或诸如执行查询的范围之类的东西? (我的意思是,也许在执行第一个查询的方法之后,实例池被清除,所以,除非第二个查询在同一个方法中,否则它将再次查询数据库。或者也许当对象还活着时,我不'不知道)
我搜索了一下,但没有找到任何东西,我的直觉告诉我,这取决于所使用的内存,但是,没有任何官方消息。
或者也许有更好的方法来做到这一点。
最佳答案
只是在我上面的评论之后添加一个答案。
基本上,实例池是按主键组织的对象的集合。它不是查询缓存,而是特定实例之一。几乎任何时候您请求特定记录时,它都会被添加到该类的实例池中。当您第二次通过主键请求该记录时,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()
方法)看看它是如何工作的。
关于php - Propel 实例池上元素的 "Duration",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15822030/