DRUPAL8模块开发 - DRUPAL8数据库API - 关于Drupal8动态查询的介绍

1、关于Drupal8动态查询的介绍

动态查询指的是由Drupal8动态生成的查询,而不是作为显式查询字符串提供的查询。
所有的插入、更新、删除、合并语句都必需是动态查询,选择语句可以是动态查询或者静态查询,隐藏,动态查询通常关联动态的选择查询。
注意:在90%的选择查询例子中,你科选择静态查询,如果从性能优先的角度考虑,你应该使用query()而不是select();
如果查询语句是变化的或者允许被修改,才使用动态语句
所有动态生成的查询都是使用查询对象构造的,查询对象是从适当的连接对象请求的。
与静态查询一样,在绝大多数情况下,可以使用程序包装器来请求对象。然而,查询的后续指令采用查询对象上调用的方法的形式。
使用select()方法启动动态选择查询,如下所示:
$query = $connection->select('mytable', 'mt', $options);
在这种情况下,mytable是查询的基本表;也就是说,在from语句之后的第一个表。注意,它不应该有括号围绕它。查询生成器将自动处理。第二个参数是表的别名。如果未指定,则使用表的名称。$options数组是可选的,与静态查询的$options数组相同。
$connection->select()调用返回的值是类型选择的对象。因此,在此调用之后$query变量中的值类型是类型选择的对象。这个对象有一个完整的方法列表,比如fields(), joins()和 group(),它们可以被调用来进一步定义查询。
动态选择查询可以非常简单或非常复杂。下面我们将介绍组成一个简单查询的各个部分,在下面的页面中,我们将看到更先进的技术,如联接。

2、大局

这里是用户表的一个相对简单的查询。

假设我们想要创建一个动态查询,它大致相当于下面的静态查询:
$result = $connection->query("SELECT uid, name, status, created, access FROM {users} u WHERE uid <> 0 LIMIT 50 OFFSET 0");
动态等值开始如下:
// Create an object of type Select
$query = $connection->select('users', 'u');
 
// Add extra detail to this query object: a condition, fields and a range
$query->condition('u.uid', 0, '<>');
$query->fields('u', ['uid', 'name', 'status', 'created', 'access']);
$query->range(0, 50);
这通常是用用于在$query 对象同时调用多个方法的速记语法编写的。因此,上面的代码通常会写成如下:
// Create an object of type Select
$query = $connection->select('users', 'u');
 
// Add extra detail to this query object: a condition, fields and a range
$query->condition('u.uid', 0, '<>')
->fields('u', ['uid', 'name', 'status', 'created', 'access'])
->range(0, 50);
事实上,通过链式调用 $connection->select() ,代码可以并且通常被简化为一步,通过调用结果对象的方法调用。如下:
// Create an object of type Select and directly 
// add extra detail to this query object: a condition, fields and a range
$query = $connection->select('users', 'u')
->condition('u.uid', 0, '<>')
->fields('u', ['uid', 'name', 'status', 'created', 'access'])
->range(0, 50);
它是用户管理页面使用的查询的简化形式,可供进一步研究参考。

3、执行查询语句

一旦查询语句被建立,调用execute()方法可以编译和运行查询。
$result = $query->execute();
execute()方法可以返回一个结果集或者语句对象,这个语句对象与$connection->query()所返回的结果完全相同,并且可以以完全相同的方式迭代或获取:

$result = $query->execute();
foreach ($result as $record) {
// Do something with each $record
}
注意:当使用下列方法获取多列、动态查询的时候要非常小心。
fetchfield()
fetchallkeyed()
fetchallassoc
fetchcol()

4、Debuging

若要检查查询对象在其生命周期中某个特定点使用的SQL查询,请打印查询对象。若要检查参数,请查看由arguments()方法返回的数组:
echo $query;
print_r($query->__toString());
print_r($query->arguments());