You are here

15 SQL语句的调用

admin 的头像
Submitted by admin on 星期四, 2015-07-30 09:22

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

曾经有人在这里,问过我一个这样的问题,我怎么没有看到SQL语句啊?我们前面讲了,在向node_page_view传递参数之前,调用了node_load函数,将节点ID转为了节点对象。我们来看一下node_load函数的定义。

/**

 * Loads a node object from the database.

 *

 * @param $nid

 *   The node ID.

 * @param $vid

 *   The revision ID.

 * @param $reset

 *   Whether to reset the node_load_multiple cache.

 *

 * @return

 *   A fully-populated node object, or FALSE if the node is not found.

 */

function node_load($nid = NULL, $vid = NULL, $reset = FALSE) {

  $nids = (isset($nid) ? array($nid) : array());

  $conditions = (isset($vid) ? array('vid' => $vid) : array());

  $node = node_load_multiple($nids, $conditions, $reset);

  return $node ? reset($node) : FALSE;

}

它将单个节点的加载委托给了node_load_multiple,只不过这里传递过来一个节点ID而已。我们往下看node_load_multiple

/**

 * Loads node entities from the database.

 *

 * This function should be used whenever you need to load more than one node

 * from the database. Nodes are loaded into memory and will not require database

 * access if loaded again during the same page request.

 *

 * @see entity_load()

 * @see EntityFieldQuery

 *

 * @param $nids

 *   An array of node IDs.

 * @param $conditions

 *   (deprecated) An associative array of conditions on the {node}

 *   table, where the keys are the database fields and the values are the

 *   values those fields must have. Instead, it is preferable to use

 *   EntityFieldQuery to retrieve a list of entity IDs loadable by

 *   this function.

 * @param $reset

 *   Whether to reset the internal node_load cache.

 *

 * @return

 *   An array of node objects indexed by nid.

 *

 * @todo Remove $conditions in Drupal 8.

 */

function node_load_multiple($nids = array(), $conditions = array(), $reset = FALSE) {

  return entity_load('node', $nids, $conditions, $reset);

}

node_load_multiple又将具体的实现,委托给了entity_load。我们通过Google搜索一下entity_load,发现这个函数位于includes/common.inc里面,这让人有点意外。Fago对这一点就提出了批评,说entity的函数放的哪都是,Drupal8在这方面做了改进,Fago的有关实体的想法进入了内核。

1.png 

     不过这里面仍然没有SQL语句。我们在这个api.drupal.org上,在代码的上面,有这么一部分:

2.png 

我们点击DrupalDefaultEntityController,进入页面https://api.drupal.org/api/drupal/includes%21entity.inc/class/DrupalDefaultEntityController/7,找到:

3.png 

点击这里的DrupalDefaultEntityController::load。阅读这个成员函数,在代码里面找到:

4.png 

我们看到SQL语句的构建,是由DrupalDefaultEntityController::buildQuery完成的,我们点击这个成员函数,查看对应的源代码,这里面,我们看到了SQL语句:

protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) {

  $query = db_select($this->entityInfo['base table'], 'base');

 

  $query->addTag($this->entityType . '_load_multiple');

 

  if ($revision_id) {

    $query->join($this->revisionTable, 'revision', "revision.{$this->idKey} = base.{$this->idKey} AND revision.{$this->revisionKey} = :revisionId", array(':revisionId' => $revision_id));

  }

  elseif ($this->revisionKey) {

    $query->join($this->revisionTable, 'revision', "revision.{$this->revisionKey} = base.{$this->revisionKey}");

  }

 

  // Add fields from the {entity} table.

  $entity_fields = $this->entityInfo['schema_fields_sql']['base table'];

 

  if ($this->revisionKey) {

    // Add all fields from the {entity_revision} table.

    $entity_revision_fields = drupal_map_assoc($this->entityInfo['schema_fields_sql']['revision table']);

    // The id field is provided by entity, so remove it.

    unset($entity_revision_fields[$this->idKey]);

 

    // Remove all fields from the base table that are also fields by the same

    // name in the revision table.

    $entity_field_keys = array_flip($entity_fields);

    foreach ($entity_revision_fields as $key => $name) {

      if (isset($entity_field_keys[$name])) {

        unset($entity_fields[$entity_field_keys[$name]]);

      }

    }

    $query->fields('revision', $entity_revision_fields);

  }

 

  $query->fields('base', $entity_fields);

 

  if ($ids) {

    $query->condition("base.{$this->idKey}", $ids, 'IN');

  }

  if ($conditions) {

    foreach ($conditions as $field => $value) {

      $query->condition('base.' . $field, $value);

    }

  }

  return $query;

}

这段代码仍然很抽象,从这里面,我们可以看出,DrupalPHP的基础之上,为我们封装了很多层。


Drupal版本: