在 Drupal 7 中操作数据库 - 第3课 - 静态查询(SELECT)
在 Drupal 中最常见的查询形式是静态查询(Static Query)。静态查询会直接、完整地传递给数据库。只有 SELECT 查询可以是静态的。
静态查询仅适用于非常简单的场景。如果你需要构建复杂的、可动态生成或执行后可修改的查询,应该使用动态查询(Dynamic Query)。
执行静态查询的最简单方式是使用查询方法:
<?php $result = $conn->query("SELECT nid, title FROM {node}"); ?>
但更推荐使用过程式封装函数:
<?php $result = db_query("SELECT nid, title FROM {node}"); ?>
上述调用等价于以下语句:
在 Drupal 7 中操作数据库 - 第4课 - 动态查询(SELECT)
我们终于来到了 Drupal Database API 中最有趣的部分:动态查询(Dynamic Queries)。之所以称为动态查询,是因为 Drupal 会动态地构建 SQL 查询语句。所有的插入(INSERT)、更新(UPDATE)、删除(DELETE)和合并(MERGE)查询都可以是动态的。SELECT 查询既可以是静态的,也可以是动态的,但在大多数情况下,推荐使用动态查询。
所有 动态查询 都是通过创建查询对象的方式生成的,我们可以在需要时对该对象进行操作。与静态查询类似,大多数动态查询也通过过程式封装函数(procedural wrapper)来执行。查询对象可以根据需要添加参数或条件。
db_select() 查询
动态 SELECT 查询从 db_select() 函数开始,例如:
在 Drupal 7 中操作数据库 - 第5课 - Extenders(扩展器)
在 Drupal 7 中,SELECT 查询支持使用 扩展(Extenders)。扩展允许在运行时为查询对象添加额外功能,这些功能可以是新增的方法,也可以修改现有方法的行为。
在面向对象编程(OOP)中,这种机制通过设计模式实现,具体来说是采用了 装饰者模式(Decorator Pattern)。扩展通过为动态对象附加额外职责,为查询对象提供一种灵活的功能增强方式。
使用 Extenders(扩展)
要使用扩展,首先必须有一个查询对象。调用查询对象的 extend() 方法会返回一个新的查询对象,该对象包含扩展功能。例如:
在 Drupal 7 中操作数据库 - 第6课 - 动态修改查询(hook_query_alter)
动态选择查询(SELECT)的一个重要特性是,其他模块可以在运行时修改查询。这允许模块向查询中插入自己的指令,从而影响查询的行为,或在执行时进行修改,例如为节点(node)添加访问权限过滤。实现动态修改查询的机制包括三个部分:tagging(标签)、meta data(元数据) 和 hook_query_alter()。
Tagging(标签)
任何动态查询都可以添加一个或多个标签(tag)。这些标签用于标识查询类型,使其他模块能够识别并对其进行相应的处理。标签应为小写字母和数字的组合,遵循与 PHP 变量相同的命名规则。要为查询添加标签,请使用 addTag() 方法:
<?php $query->addTag('node_access'); ?>
可以使用以下三种方法来检测查询对象中是否存在标签:
在 Drupal 7 中操作数据库 - 第7课 - 查询结果的处理(fetch)
SELECT 查询的执行结果总是返回 0 条或多条记录。对于查询结果的处理,Drupal 提供了多种方式,您可以根据实际需求选择使用。
最常见的方式是通过 foreach() 循环遍历结果:
<?php $result = db_query("SELECT nid, title FROM {node}"); foreach ($result as $record) { // 处理每一条记录 $node = node_load($record->nid); } ?>
根据你需要的输出形式,你还可以使用其他方式来获取结果记录。若需逐条显式读取记录,请使用以下方法:
在 Drupal 7 中操作数据库 - 第8课 - 插入查询(INSERT INTO)
插入查询应始终使用查询构造器(Query Builder)。某些数据库需要对 LOB(Large Object,例如 MySQL 中的 TEXT)和 BLOB(Binary Large Object)字段进行特殊处理,因此需要通过数据库抽象层为不同的数据库驱动实现相应的处理逻辑。
插入查询以函数 db_insert() 开始:
<?php $query = db_insert('node', $options); ?>
该插入查询会创建一个查询对象,用于向表 node 中插入一条或多条记录。请注意,不需要使用花括号包裹表名,查询构造器会自动处理。
插入查询使用 Fluent API(链式调用),这意味着所有方法(包括 execute())都会返回查询对象自身,从而可以连续调用多个方法。
插入查询支持多种模式以适应不同用途。通常,我们先定义要插入的字段,然后指定要插入的值。以下列出了常见的几种使用模式。
在 Drupal 7 中操作数据库 - 第9课 - 更新查询(UPDATE)
更新查询应始终使用查询构造器(Query Builder)。不同的数据库对 LOB(Large Object,如 MySQL 中的 TEXT)和 BLOB(Binary Large Object)字段有各自的处理方式,因此需要在数据库抽象层中为每个驱动实现特定的处理逻辑。
更新查询从函数 db_update() 开始:
<?php $query = db_update('node', $options); ?>
通过创建此更新查询对象,我们可以修改表 node 中的一条或多条记录。请注意,不需要使用花括号包裹表名,查询构造器会自动处理。
更新查询对象使用 Fluent API(链式调用),因此除 execute() 外的所有方法都会返回查询对象自身,从而支持方法链调用。在大多数情况下,这意味着查询不需要存储为变量。
在 Drupal 7 中操作数据库 - 第10课 - 删除查询(DELETE)
删除查询应使用查询构造器(Query Builder)。它们从函数 db_delete() 开始:
<?php $query = db_delete('node', $options); ?>
此删除查询将从表 node 中删除记录。请注意,无需在表名外加花括号,查询构造器会自动处理。删除查询使用 Fluent API(链式调用),即除 execute() 之外的所有方法都会返回查询对象本身(与更新 UPDATE 和插入 INSERT 查询相同)。
删除查询非常简单,仅使用 WHERE 表达式。关于 WHERE 的详细内容将在后续课程中讲解,现在我们来看一个基本的删除示例:
在 Drupal 7 中操作数据库 - 第11课 - 合并查询(MERGE)
合并查询是一种特殊的混合类型查询。尽管这种语法在 SQL 2003 中被定义,但实际上几乎没有数据库原生支持该语法。然而,大多数数据库都提供了各自特定的替代实现。Drupal 中的合并查询构造器(Merge Query Builder)将“合并查询”的概念抽象为对象结构,这样系统可以根据不同数据库的特性分别编译对应的查询语句。
总体而言,合并查询是 INSERT 与 UPDATE 查询的组合。如果满足某个条件(例如表中存在指定键的记录),则执行一个查询;否则执行另一个查询。大多数情况下,它等价于以下逻辑:
在 Drupal 7 中操作数据库 - 第12课 - 查询条件(WHERE、HAVING、LIKE)
查询条件允许我们选择仅符合特定限制的记录,例如两周内创建的节点、名称中包含“Drupal”一词的术语等。在 SQL 中,我们使用 WHERE 和 HAVING 来为 SELECT、UPDATE、DELETE 查询设置限制。在 Drupal 的动态查询中,也提供了用于处理查询条件的机制。这个机制在三种类型的查询(选择、更新、删除)中工作方式相同。
条件表达式的概念
条件包含在一个专门定义限制的表达式中。
合并(相加、并集、逻辑与)
每个条件可以由多个条件表达式组成,这些表达式可以组合在一起。条件通过运算符 AND(与) 和 OR(或) 来连接。
条件对象
Drupal 将每个条件片段表示为 QueryConditional 类的实例。条件对象是该类的一个实例。
我们来看一个 SQL 查询示例:
查询语句: