9

我正在使用 Propel 1.6,但我不确定如何从 propel 对象集合中获取对象(给定其“id”属性值)。我在 Propel 的文档中找不到直接的答案(PropelCollection 方法似乎不适用?)。例如:假设我有一个具有以下架构的“Person”表:

<table name="person">
  <column name="id" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
  <column name="name" type="VARCHAR" size="100" required="true"/>
</table>

我执行以下查询以获取“Person”对象的集合:

$persons = PersonQuery::create()->find();

然后,我想找到一个具有给定“id”的“Person”对象(例如“id=3”的“Person”),而不需要对数据库进行新的查询。我该怎么做?

$persons->get(...?)?

换句话说,我不想这样做:

$personX = PersonQuery::create()->findOneById(3);

语境:

我想阻止进行数据库查询以提高性能。该语句将插入到 foreach 语句中,否则会导致大量数据库连接,如下所示:

foreach ($books as $book) {
    $book['author_name'] = PersonQuery::create()->findOneById($book['author_id'])->getName();
}
4

5 回答 5

8

另一种选择,特别是如果您需要多次搜索,是使用 $collection->getArrayCopy('Id') 按 id 获取对象数组。

$persons = PersonQuery::create()->find();
$personsById = $persons->getArrayCopy('Id');

然后你可以做

$person = $personsById[3];

或者

if (isset($personsById[3])) {
  $person = $personsById[3];
  ...
}
于 2014-07-25T20:04:20.100 回答
4

好吧,这不会很有效,但是您可以通过集合找到它。

$persons = PersonQuery::create()->find();
foreach ($persons as $person)
{
  if (3 == $person->getId())
  {
    break;
  }
}

// now you have your person with id = 3
var_dump($person->getId());
于 2012-09-03T16:34:12.107 回答
3

由于 Propel 没有正确缓存查询结果,因此您需要迭代集合(如@j0k所说)。foreach您可以调用array_filter传递闭包而不是使用循环(使用 PHP 5.3)。

// Request the persons
$persons = PersonQuery::create()->find();

// Filter the persons whose ID equals 3
$filteredPersons = array_filter($persons, function ($person) {
    return 3 === $person->getId();
});

// Get the first result
$person = empty($filteredPersons) ? null : $filteredPersons[0];

如果您确定会找到此人,您还可以编写(使用 PHP 5.4)以下行:

// Filter the person whose ID equals 3
$person = array_filter($persons, function ($person) {
    return 3 === $person->getId();
})[0];
于 2012-09-04T08:12:49.050 回答
2

如果你设置 Propel::isInstancePoolingEnabled() 为真(默认为真),那么你可以

// Request the persons
$persons = PersonQuery::create()->find();
// get person from pool
$person = PersonPeer::getInstanceFromPool(3);

对不起我的英语。

于 2013-08-26T09:41:06.720 回答
1

对于 user2663223 的答案,Propel >=1.5 的替代方案是:

$persons = PersonQuery::create()->find()

$person = PersonQuery::create()->findPk(3);

这利用了实例池。它在内部使用:getInstanceFromPool,如果之前完成了 sql 查询。

欲了解更多信息,请咨询:

http://propelorm.org/documentation/03-basic-crud.html#propel-instance-pool

于 2014-07-11T12:42:41.853 回答