查询构建器类
CodeIgniter 为您提供了查询构建器类。这种模式允许您以最少的脚本操作检索、插入和更新数据库中的信息。在某些情况下,只需一两行代码即可执行数据库操作。CodeIgniter 不需要每个数据库表都成为自己的类文件。相反,它提供了一个更简化的接口。
除了简单性之外,使用查询构建器功能的主要好处是它允许您创建与数据库无关的应用程序,因为查询语法是由每个数据库适配器生成的。它还允许更安全的查询,因为系统会自动转义值。
注意
CodeIgniter 不支持数据库、表和列名称中的点 (.
)。
SQL 注入保护
您可以使用查询构建器安全地生成 SQL 语句。但是,它并非旨在防止 SQL 注入,无论您传递什么数据。
- 传递给查询构建器的参数可以是
标识符,例如字段(或表)名称
它们的值
SQL 字符串的一部分
查询构建器默认情况下会转义所有值。
它还将尝试默认情况下正确保护标识符和SQL 字符串中的标识符。但是,它的实现是为了在许多用例中都能正常工作,并非旨在防止所有攻击。因此,您永远不要在没有适当验证的情况下将用户输入馈送到它们。
此外,许多方法都有$escape
参数,可以将其设置为禁用转义。如果将$escape
设置为 false,则查询构建器不会提供任何保护,因此您必须自行确保在将其传递给查询构建器之前对其进行适当转义或保护。使用RawSql
时也是如此,它指定原始 SQL 语句。
加载查询构建器
查询构建器通过数据库连接上的table()
方法加载。这会为您设置查询的FROM部分,并返回查询构建器类的新的实例
<?php
$db = \Config\Database::connect();
$builder = $db->table('users');
只有在您明确请求该类时,查询构建器才会加载到内存中,因此默认情况下不会使用任何资源。
选择数据
以下方法允许您构建 SQL SELECT 语句。
Get
$builder->get()
运行选择查询并返回结果。可以单独使用它来检索表中的所有记录
<?php
$builder = $db->table('mytable');
$query = $builder->get(); // Produces: SELECT * FROM mytable
第一个和第二个参数允许您设置限制和偏移子句。
<?php
$query = $builder->get(10, 20);
/*
* Executes: SELECT * FROM mytable LIMIT 20, 10
* (in MySQL. Other databases have slightly different syntax)
*/
您会注意到,上述方法被分配给一个名为 $query 的变量,该变量可用于显示结果。
<?php
$query = $builder->get();
foreach ($query->getResult() as $row) {
echo $row->title;
}
请访问 getResult*() 方法 页面,以全面了解结果生成。
$builder->getCompiledSelect()
编译选择查询,就像 $builder->get()
一样,但不会 *运行* 查询。此方法仅将 SQL 查询作为字符串返回。
示例
<?php
$sql = $builder->getCompiledSelect();
echo $sql;
// Prints string: SELECT * FROM mytable
第一个参数允许您设置查询构建器查询是否将被重置(默认情况下它将被重置,就像使用 $builder->get()
时一样)。
<?php
echo $builder->limit(10, 20)->getCompiledSelect(false);
/*
* Prints string: SELECT * FROM mytable LIMIT 20, 10
* (in MySQL. Other databases have slightly different syntax)
*/
echo $builder->select('title, content, date')->getCompiledSelect();
// Prints string: SELECT title, content, date FROM mytable LIMIT 20, 10
在上面的示例中需要注意的关键是,第二个查询没有使用 limit(10, 20)
,但生成的 SQL 查询有 LIMIT 20, 10
。出现这种情况的原因是第一个参数设置为 false
。
$builder->getWhere()
与 get()
方法相同,只是它允许您在第一个参数中添加“where”子句,而不是使用 $builder->where()
方法。
<?php
$query = $builder->getWhere(['id' => $id], $limit, $offset);
请阅读下面关于 where()
方法的更多信息。
选择
$builder->select()
允许您编写查询的 **SELECT** 部分。
<?php
$builder->select('title, content, date');
$query = $builder->get();
// Executes: SELECT title, content, date FROM mytable
注意
如果您从表中选择所有 (*
),则不需要使用此方法。省略时,CodeIgniter 假设您希望选择所有字段并自动添加 SELECT *
。
$builder->select()
接受一个可选的第二个参数。如果您将其设置为 false
,CodeIgniter 将不会尝试保护您的字段或表名。如果您需要一个复合选择语句,其中字段的自动转义可能会破坏它们,这将很有用。
<?php
$builder->select('(SELECT SUM(payments.amount) FROM payments WHERE payments.invoice_id=4) AS amount_paid', false);
$query = $builder->get();
RawSql
版本 4.2.0 中新增。
从 v4.2.0 开始,$builder->select()
接受一个 CodeIgniter\Database\RawSql
实例,用于表达原始 SQL 字符串。
<?php
use CodeIgniter\Database\RawSql;
$sql = 'REGEXP_SUBSTR(ral_anno,"[0-9]{1,2}([,.][0-9]{1,3})([,.][0-9]{1,3})") AS ral';
$builder->select(new RawSql($sql));
$query = $builder->get();
警告
使用 RawSql
时,您 **必须** 手动转义值并保护标识符。否则可能会导致 SQL 注入。
$builder->selectMax()
为您的查询编写一个 **SELECT MAX(field)** 部分。您可以选择包含第二个参数来重命名结果字段。
<?php
$builder->selectMax('age');
$query = $builder->get();
// Produces: SELECT MAX(age) as age FROM mytable
$builder->selectMax('age', 'member_age');
$query = $builder->get();
// Produces: SELECT MAX(age) as member_age FROM mytable
$builder->selectMin()
为您的查询编写一个 **SELECT MIN(field)** 部分。与 selectMax()
一样,您可以选择包含第二个参数来重命名结果字段。
<?php
$builder->selectMin('age');
$query = $builder->get();
// Produces: SELECT MIN(age) as age FROM mytable
$builder->selectAvg()
为您的查询编写一个 **SELECT AVG(field)** 部分。与 selectMax()
一样,您可以选择包含第二个参数来重命名结果字段。
<?php
$builder->selectAvg('age');
$query = $builder->get();
// Produces: SELECT AVG(age) as age FROM mytable
$builder->selectSum()
为您的查询编写一个 **SELECT SUM(field)** 部分。与 selectMax()
一样,您可以选择包含第二个参数来重命名结果字段。
<?php
$builder->selectSum('age');
$query = $builder->get();
// Produces: SELECT SUM(age) as age FROM mytable
$builder->selectCount()
为您的查询编写一个 **SELECT COUNT(field)** 部分。与 selectMax()
一样,您可以选择包含第二个参数来重命名结果字段。
注意
此方法在与 groupBy()
一起使用时特别有用。要计算一般结果,请参见 countAll()
或 countAllResults()
。
<?php
$builder->selectCount('age');
$query = $builder->get();
// Produces: SELECT COUNT(age) as age FROM mytable
$builder->selectSubquery()
在 SELECT 部分添加子查询。
$subquery = $db->table('countries')->select('name')->where('id', 1);
$builder = $db->table('users')->select('name')->selectSubquery($subquery, 'country');
$query = $builder->get();
// Produces: SELECT `name`, (SELECT `name` FROM `countries` WHERE `id` = 1) `country` FROM `users`
From
$builder->from()
允许您编写查询的 **FROM** 部分
<?php
$builder = $db->table('users');
$builder->select('title, content, date');
$builder->from('mytable');
$query = $builder->get();
// Produces: SELECT title, content, date FROM users, mytable
注意
如前所述,查询的 **FROM** 部分可以在 $db->table()
方法中指定。对 from()
的额外调用将向查询的 FROM 部分添加更多表。
子查询
$builder->fromSubquery()
允许您将 **FROM** 查询的一部分写成子查询。
这是我们在现有表中添加子查询的地方。
<?php
$subquery = $db->table('users');
$builder = $db->table('jobs')->fromSubquery($subquery, 'alias');
$query = $builder->get();
// Produces: SELECT * FROM `jobs`, (SELECT * FROM `users`) `alias`
使用 $db->newQuery()
方法将子查询作为主表。
<?php
$subquery = $db->table('users')->select('id, name');
$builder = $db->newQuery()->fromSubquery($subquery, 't');
$query = $builder->get();
// Produces: SELECT * FROM (SELECT `id`, `name` FROM users) `t`
连接
$builder->join()
允许您编写查询的 **JOIN** 部分。
<?php
$builder = $db->table('blogs');
$builder->select('*');
$builder->join('comments', 'comments.id = blogs.id');
$query = $builder->get();
/*
* Produces:
* SELECT * FROM blogs JOIN comments ON comments.id = blogs.id
*/
如果您在一个查询中需要多个连接,可以进行多次方法调用。
如果您需要特定类型的 **JOIN**,可以通过方法的第三个参数指定它。选项包括:left
、right
、outer
、inner
、left outer
和 right outer
。
<?php
$builder->join('comments', 'comments.id = blogs.id', 'left');
// Produces: LEFT JOIN comments ON comments.id = blogs.id
RawSql
版本 4.2.0 中新增。
从 v4.2.0 开始,$builder->join()
接受一个 CodeIgniter\Database\RawSql
实例,该实例表示原始 SQL 字符串。
<?php
use CodeIgniter\Database\RawSql;
$sql = 'user.id = device.user_id AND ((1=1 OR 1=1) OR (1=1 OR 1=1))';
$builder->join('user', new RawSql($sql), 'LEFT');
// Produces: LEFT JOIN "user" ON user.id = device.user_id AND ((1=1 OR 1=1) OR (1=1 OR 1=1))
警告
使用 RawSql
时,您 **必须** 手动转义值并保护标识符。否则可能会导致 SQL 注入。
查找特定数据
Where
$builder->where()
此方法允许您使用五种方法之一设置 **WHERE** 子句
注意
传递给此方法的所有值都会自动转义,生成更安全的查询,除非使用自定义字符串。
注意
$builder->where()
接受一个可选的第三个参数。如果将其设置为 false
,CodeIgniter 将不会尝试保护您的字段或表名。
1. 简单键值方法
<?php $builder->where('name', $name); // Produces: WHERE name = 'Joe'请注意,等号会为您添加。
如果您使用多个方法调用,它们将使用 **AND** 在它们之间连接起来
<?php $builder->where('name', $name); $builder->where('title', $title); $builder->where('status', $status); // WHERE name = 'Joe' AND title = 'boss' AND status = 'active'
2. 自定义键值方法
您可以在第一个参数中包含一个运算符来控制比较
<?php $builder->where('name !=', $name); $builder->where('id <', $id); // Produces: WHERE name != 'Joe' AND id < 45
3. 关联数组方法
<?php $array = ['name' => $name, 'title' => $title, 'status' => $status]; $builder->where($array); // Produces: WHERE name = 'Joe' AND title = 'boss' AND status = 'active'您也可以使用此方法包含自己的运算符
<?php $array = ['name !=' => $name, 'id <' => $id, 'date >' => $date]; $builder->where($array);
4. 自定义字符串
您可以手动编写自己的子句
<?php $where = "name='Joe' AND status='boss' OR status='active'"; $builder->where($where);警告
如果您在字符串中使用用户提供的数据,您必须手动转义值并保护标识符。否则可能会导致 SQL 注入。
<?php $name = $builder->db->escape('Joe'); $where = "name={$name} AND status='boss' OR status='active'"; $builder->where($where);
5. RawSql
版本 4.2.0 中新增。
从 v4.2.0 开始,
$builder->where()
接受一个CodeIgniter\Database\RawSql
实例,它表示原始 SQL 字符串。<?php use CodeIgniter\Database\RawSql; $sql = "id > 2 AND name != 'Accountant'"; $builder->where(new RawSql($sql));警告
使用
RawSql
时,您 **必须** 手动转义值并保护标识符。否则可能会导致 SQL 注入。
6. 子查询
<?php // With closure use CodeIgniter\Database\BaseBuilder; $builder->where('advance_amount <', static function (BaseBuilder $builder) { $builder->select('MAX(advance_amount)', false)->from('orders')->where('id >', 2); }); // Produces: WHERE "advance_amount" < (SELECT MAX(advance_amount) FROM "orders" WHERE "id" > 2) // With builder directly $subQuery = $db->table('orders')->select('MAX(advance_amount)', false)->where('id >', 2); $builder->where('advance_amount <', $subQuery);
$builder->orWhere()
此方法与上面的方法相同,只是多个实例通过 **OR** 连接起来
<?php
$builder->where('name !=', $name);
$builder->orWhere('id >', $id);
// Produces: WHERE name != 'Joe' OR id > 50
$builder->whereIn()
生成一个 **WHERE** 字段 IN (‘item’, ‘item’) SQL 查询,如果合适,则使用 **AND** 连接
<?php
$names = ['Frank', 'Todd', 'James'];
$builder->whereIn('username', $names);
// Produces: WHERE username IN ('Frank', 'Todd', 'James')
您可以使用子查询而不是值数组
<?php
// With closure
use CodeIgniter\Database\BaseBuilder;
$builder->whereIn('id', static function (BaseBuilder $builder) {
$builder->select('job_id')->from('users_jobs')->where('user_id', 3);
});
// Produces: WHERE "id" IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3)
// With builder directly
$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3);
$builder->whereIn('id', $subQuery);
$builder->orWhereIn()
生成一个 **WHERE 字段 IN (‘item’, ‘item’)** SQL 查询,如果合适,则使用 **OR** 连接
<?php
$names = ['Frank', 'Todd', 'James'];
$builder->orWhereIn('username', $names);
// Produces: OR username IN ('Frank', 'Todd', 'James')
您可以使用子查询而不是值数组
<?php
// With closure
use CodeIgniter\Database\BaseBuilder;
$builder->orWhereIn('id', static function (BaseBuilder $builder) {
$builder->select('job_id')->from('users_jobs')->where('user_id', 3);
});
// Produces: OR "id" IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3)
// With builder directly
$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3);
$builder->orWhereIn('id', $subQuery);
$builder->whereNotIn()
生成一个 **WHERE 字段 NOT IN (‘item’, ‘item’)** SQL 查询,如果合适,则使用 **AND** 连接
<?php
$names = ['Frank', 'Todd', 'James'];
$builder->whereNotIn('username', $names);
// Produces: WHERE username NOT IN ('Frank', 'Todd', 'James')
您可以使用子查询而不是值数组
<?php
// With closure
use CodeIgniter\Database\BaseBuilder;
$builder->whereNotIn('id', static function (BaseBuilder $builder) {
$builder->select('job_id')->from('users_jobs')->where('user_id', 3);
});
// Produces: WHERE "id" NOT IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3)
// With builder directly
$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3);
$builder->whereNotIn('id', $subQuery);
$builder->orWhereNotIn()
生成一个WHERE field NOT IN (‘item’, ‘item’) SQL 查询,如果合适则与OR 连接
<?php
$names = ['Frank', 'Todd', 'James'];
$builder->orWhereNotIn('username', $names);
// Produces: OR username NOT IN ('Frank', 'Todd', 'James')
您可以使用子查询而不是值数组
<?php
// With closure
use CodeIgniter\Database\BaseBuilder;
$builder->orWhereNotIn('id', static function (BaseBuilder $builder) {
$builder->select('job_id')->from('users_jobs')->where('user_id', 3);
});
// Produces: OR "id" NOT IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3)
// With builder directly
$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3);
$builder->orWhereNotIn('id', $subQuery);
寻找类似的数据
Like
$builder->like()
此方法允许您生成LIKE 子句,这对于执行搜索非常有用。
注意
传递给此方法的所有值都会自动转义。
注意
所有 like*
方法变体都可以通过将第五个参数设置为 true
来强制执行不区分大小写的搜索。这将使用平台特定的功能(如果可用),否则将强制值变为小写,即 WHERE LOWER(column) LIKE '%search%'
。这可能需要为 LOWER(column)
而不是 column
创建索引才能有效。
1. 简单键值方法
<?php $builder->like('title', 'match'); // Produces: WHERE `title` LIKE '%match%' ESCAPE '!'如果您使用多个方法调用,它们将使用 **AND** 在它们之间连接起来
<?php $builder->like('title', 'match'); $builder->like('body', 'match'); // WHERE `title` LIKE '%match%' ESCAPE '!' AND `body` LIKE '%match%' ESCAPE '!'如果您想控制通配符 (%) 的放置位置,可以使用可选的第三个参数。您的选项是
before
、after
和both
(这是默认值)。<?php $builder->like('title', 'match', 'before'); // Produces: WHERE `title` LIKE '%match' ESCAPE '!' $builder->like('title', 'match', 'after'); // Produces: WHERE `title` LIKE 'match%' ESCAPE '!' $builder->like('title', 'match', 'both'); // Produces: WHERE `title` LIKE '%match%' ESCAPE '!'
2. 关联数组方法
<?php $array = ['title' => $match, 'page1' => $match, 'page2' => $match]; $builder->like($array); /* * WHERE `title` LIKE '%match%' ESCAPE '!' * AND `page1` LIKE '%match%' ESCAPE '!' * AND `page2` LIKE '%match%' ESCAPE '!' */
3. RawSql
版本 4.2.0 中新增。
从 v4.2.0 开始,
$builder->like()
接受一个CodeIgniter\Database\RawSql
实例,该实例表示原始 SQL 字符串。<?php use CodeIgniter\Database\RawSql; $sql = "CONCAT(users.name, ' ', IF(users.surname IS NULL OR users.surname = '', '', users.surname))"; $rawSql = new RawSql($sql); $builder->like($rawSql, 'value', 'both');警告
使用
RawSql
时,您 **必须** 手动转义值并保护标识符。否则可能会导致 SQL 注入。
$builder->orLike()
此方法与上面的方法相同,只是多个实例通过 **OR** 连接起来
<?php
$builder->like('title', 'match');
$builder->orLike('body', $match);
// WHERE `title` LIKE '%match%' ESCAPE '!' OR `body` LIKE '%match%' ESCAPE '!'
$builder->notLike()
此方法与 like()
相同,只是它生成NOT LIKE 语句
<?php
$builder->notLike('title', 'match'); // WHERE `title` NOT LIKE '%match% ESCAPE '!'
$builder->orNotLike()
此方法与 notLike()
相同,只是多个实例由 OR 连接
<?php
$builder->like('title', 'match');
$builder->orNotLike('body', 'match');
// WHERE `title` LIKE '%match% OR `body` NOT LIKE '%match%' ESCAPE '!'
$builder->groupBy()
允许您编写查询的 GROUP BY 部分
<?php
$builder->groupBy('title');
// Produces: GROUP BY title
您也可以传递一个包含多个值的数组
<?php
$builder->groupBy(['title', 'date']);
// Produces: GROUP BY title, date
$builder->distinct()
在查询中添加 DISTINCT 关键字
<?php
$builder->distinct();
$builder->get();
// Produces: SELECT DISTINCT * FROM mytable
$builder->having()
允许您编写查询的 HAVING 部分。有两种可能的语法,一个参数或两个参数
<?php
$builder->having('user_id = 45'); // Produces: HAVING user_id = 45
$builder->having('user_id', 45); // Produces: HAVING user_id = 45
您也可以传递一个包含多个值的数组
<?php
$builder->having(['title =' => 'My Title', 'id <' => $id]);
// Produces: HAVING title = 'My Title', id < 45
如果您使用的是 CodeIgniter 为其转义值的数据库,您可以通过传递一个可选的第三个参数并将其设置为 false
来阻止转义内容。
<?php
$builder->having('user_id', 45); // Produces: HAVING `user_id` = 45 in some databases such as MySQL
$builder->having('user_id', 45, false); // Produces: HAVING user_id = 45
$builder->orHaving()
与 having()
相同,只是用 OR 分隔多个子句。
$builder->havingIn()
生成一个 HAVING field IN (‘item’, ‘item’) SQL 查询,如果合适,则用 AND 连接
<?php
$groups = [1, 2, 3];
$builder->havingIn('group_id', $groups);
// Produces: HAVING group_id IN (1, 2, 3)
您可以使用子查询而不是值数组
<?php
// With closure
use CodeIgniter\Database\BaseBuilder;
$builder->havingIn('id', static function (BaseBuilder $builder) {
$builder->select('user_id')->from('users_jobs')->where('group_id', 3);
});
// Produces: HAVING "id" IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3)
// With builder directly
$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3);
$builder->havingIn('id', $subQuery);
$builder->orHavingIn()
生成一个 HAVING field IN (‘item’, ‘item’) SQL 查询,如果合适,则用 OR 连接
<?php
$groups = [1, 2, 3];
$builder->orHavingIn('group_id', $groups);
// Produces: OR group_id IN (1, 2, 3)
您可以使用子查询而不是值数组
<?php
// With closure
use CodeIgniter\Database\BaseBuilder;
$builder->orHavingIn('id', static function (BaseBuilder $builder) {
$builder->select('user_id')->from('users_jobs')->where('group_id', 3);
});
// Produces: OR "id" IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3)
// With builder directly
$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3);
$builder->orHavingIn('id', $subQuery);
$builder->havingNotIn()
生成一个 HAVING field NOT IN (‘item’, ‘item’) SQL 查询,如果合适,则用 AND 连接
<?php
$groups = [1, 2, 3];
$builder->havingNotIn('group_id', $groups);
// Produces: HAVING group_id NOT IN (1, 2, 3)
您可以使用子查询而不是值数组
<?php
// With closure
use CodeIgniter\Database\BaseBuilder;
$builder->havingNotIn('id', static function (BaseBuilder $builder) {
$builder->select('user_id')->from('users_jobs')->where('group_id', 3);
});
// Produces: HAVING "id" NOT IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3)
// With builder directly
$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3);
$builder->havingNotIn('id', $subQuery);
$builder->orHavingNotIn()
生成一个 HAVING field NOT IN (‘item’, ‘item’) SQL 查询,如果合适,则用 OR 连接
<?php
$groups = [1, 2, 3];
$builder->havingNotIn('group_id', $groups);
// Produces: OR group_id NOT IN (1, 2, 3)
您可以使用子查询而不是值数组
<?php
// With closure
use CodeIgniter\Database\BaseBuilder;
$builder->orHavingNotIn('id', static function (BaseBuilder $builder) {
$builder->select('user_id')->from('users_jobs')->where('group_id', 3);
});
// Produces: OR "id" NOT IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3)
// With builder directly
$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3);
$builder->orHavingNotIn('id', $subQuery);
$builder->havingLike()
此方法使您能够为查询的 HAVING 部分生成 LIKE 子句,这对于执行搜索很有用。
注意
传递给此方法的所有值都会自动转义。
注意
所有 havingLike*()
方法变体都可以通过将第五个参数传递给方法并将其设置为 true
来强制执行不区分大小写的搜索。这将使用平台特定的功能(如果可用),否则将强制值变为小写,即 HAVING LOWER(column) LIKE '%search%'
。这可能需要为 LOWER(column)
而不是 column
创建索引才能有效。
1. 简单键值方法
<?php $builder->havingLike('title', 'match'); // Produces: HAVING `title` LIKE '%match%' ESCAPE '!'如果您使用多个方法调用,它们将使用 **AND** 在它们之间连接起来
<?php $builder->havingLike('title', 'match'); $builder->havingLike('body', 'match'); // HAVING `title` LIKE '%match%' ESCAPE '!' AND `body` LIKE '%match% ESCAPE '!'如果您想控制通配符 (%) 的放置位置,可以使用可选的第三个参数。您的选项是
before
、after
和both
(这是默认值)。<?php $builder->havingLike('title', 'match', 'before'); // Produces: HAVING `title` LIKE '%match' ESCAPE '!' $builder->havingLike('title', 'match', 'after'); // Produces: HAVING `title` LIKE 'match%' ESCAPE '!' $builder->havingLike('title', 'match', 'both'); // Produces: HAVING `title` LIKE '%match%' ESCAPE '!'
2. 关联数组方法
<?php $array = ['title' => $match, 'page1' => $match, 'page2' => $match]; $builder->havingLike($array); /* * HAVING `title` LIKE '%match%' ESCAPE '!' * AND `page1` LIKE '%match%' ESCAPE '!' * AND `page2` LIKE '%match%' ESCAPE '!' */
$builder->orHavingLike()
此方法与上面的方法相同,只是多个实例通过 **OR** 连接起来
<?php
$builder->havingLike('title', 'match');
$builder->orHavingLike('body', $match);
// HAVING `title` LIKE '%match%' ESCAPE '!' OR `body` LIKE '%match%' ESCAPE '!'
$builder->notHavingLike()
此方法与 havingLike()
相同,只是它生成 **NOT LIKE** 语句。
<?php
$builder->notHavingLike('title', 'match');
// HAVING `title` NOT LIKE '%match% ESCAPE '!'
$builder->orNotHavingLike()
此方法与 notHavingLike()
相同,只是多个实例由 **OR** 连接。
<?php
$builder->havingLike('title', 'match');
$builder->orNotHavingLike('body', 'match');
// HAVING `title` LIKE '%match% OR `body` NOT LIKE '%match%' ESCAPE '!'
排序结果
OrderBy
$builder->orderBy()
允许您设置 **ORDER BY** 子句。
第一个参数包含您要排序的列的名称。
第二个参数允许您设置结果的方向。选项包括 ASC
、DESC
和 RANDOM
。
<?php
$builder->orderBy('title', 'DESC');
// Produces: ORDER BY `title` DESC
您也可以在第一个参数中传递您自己的字符串。
<?php
$builder->orderBy('title DESC, name ASC');
// Produces: ORDER BY `title` DESC, `name` ASC
如果您需要多个字段,也可以进行多个方法调用。
<?php
$builder->orderBy('title', 'DESC');
$builder->orderBy('name', 'ASC');
// Produces: ORDER BY `title` DESC, `name` ASC
如果您选择 RANDOM
方向选项,则第一个参数将被忽略,除非您指定一个数字种子值。
<?php
$builder->orderBy('title', 'RANDOM');
// Produces: ORDER BY RAND()
$builder->orderBy(42, 'RANDOM');
// Produces: ORDER BY RAND(42)
限制或计数结果
限制
$builder->limit()
允许您限制查询返回的行数。
<?php
$builder->limit(10);
// Produces: LIMIT 10
第二个参数允许您设置结果偏移量。
<?php
$builder->limit(10, 20);
// Produces: LIMIT 20, 10 (in MySQL. Other databases have slightly different syntax)
$builder->countAllResults()
允许您确定特定 Query Builder 查询中的行数。查询将接受 Query Builder 限制器,例如 where()
、orWhere()
、like()
、orLike()
等。示例
<?php
echo $builder->countAllResults(); // Produces an integer, like 25
$builder->like('title', 'match');
$builder->from('my_table');
echo $builder->countAllResults(); // Produces an integer, like 17
但是,此方法还会重置您可能传递给 select()
的任何字段值。如果您需要保留它们,可以将 false
作为第一个参数传递。
<?php
echo $builder->countAllResults(false); // Produces an integer, like 17
$builder->countAll()
允许您确定特定表中的行数。示例
<?php
echo $builder->countAll(); // Produces an integer, like 25
与 countAllResult()
方法一样,此方法也会重置您可能传递给 select()
的任何字段值。如果您需要保留它们,可以将 false
作为第一个参数传递。
联合查询
联合
$builder->union()
用于组合两个或多个 SELECT 语句的结果集。它将只返回唯一的结果。
<?php
$builder = $db->table('users')->select('id, name')->limit(10);
$union = $db->table('groups')->select('id, name');
$builder->union($union)->get();
/*
* Produces:
* SELECT * FROM (SELECT `id`, `name` FROM `users` LIMIT 10) uwrp0
* UNION SELECT * FROM (SELECT `id`, `name` FROM `groups`) uwrp1
*/
注意
为了与 DBMS(如 MSSQL 和 Oracle)正确工作,查询将被包装在 SELECT * FROM ( ... ) alias
中。主查询将始终具有别名 uwrp0
。每个通过 union()
添加的后续查询将具有别名 uwrpN+1
。
所有联合查询都将添加到主查询之后,无论 union()
方法的调用顺序如何。也就是说,limit()
或 orderBy()
方法将相对于主查询,即使在 union()
之后调用。
在某些情况下,可能需要对查询结果的记录进行排序或限制数量。解决方案是使用通过 $db->newQuery()
创建的包装器。在下面的示例中,我们获取前 5 个用户 + 最后 5 个用户,并按 id 对结果进行排序
<?php
$union = $db->table('users')->select('id, name')->orderBy('id', 'DESC')->limit(5);
$builder = $db->table('users')->select('id, name')->orderBy('id', 'ASC')->limit(5)->union($union);
$db->newQuery()->fromSubquery($builder, 'q')->orderBy('id', 'DESC')->get();
/*
* Produces:
* SELECT * FROM (
* SELECT * FROM (SELECT `id`, `name` FROM `users` ORDER BY `id` ASC LIMIT 5) uwrp0
* UNION
* SELECT * FROM (SELECT `id`, `name` FROM `users` ORDER BY `id` DESC LIMIT 5) uwrp1
* ) q ORDER BY `id` DESC
*/
$builder->unionAll()
行为与 union()
方法相同。但是,将返回所有结果,而不仅仅是唯一的结果。
查询分组
分组
查询分组允许您通过将 **WHERE** 子句括在括号中来创建 **WHERE** 子句组。这将允许您创建具有复杂 **WHERE** 子句的查询。支持嵌套组。示例
<?php
$builder->select('*')->from('my_table')
->groupStart()
->where('a', 'a')
->orGroupStart()
->where('b', 'b')
->where('c', 'c')
->groupEnd()
->groupEnd()
->where('d', 'd')
->get();
/*
* Generates:
* SELECT * FROM (`my_table`) WHERE ( `a` = 'a' OR ( `b` = 'b' AND `c` = 'c' ) ) AND `d` = 'd'
*/
注意
组需要平衡,确保每个 groupStart()
都与一个 groupEnd()
相匹配。
$builder->groupStart()
通过在查询的 **WHERE** 子句中添加一个左括号来开始一个新的组。
$builder->orGroupStart()
在查询的 WHERE 子句中添加一个左括号,并在其前面加上 OR,从而开始一个新的分组。
$builder->notGroupStart()
在查询的 WHERE 子句中添加一个左括号,并在其前面加上 NOT,从而开始一个新的分组。
$builder->orNotGroupStart()
在查询的 WHERE 子句中添加一个左括号,并在其前面加上 OR NOT,从而开始一个新的分组。
$builder->groupEnd()
在查询的 WHERE 子句中添加一个右括号,从而结束当前分组。
$builder->havingGroupStart()
在查询的 HAVING 子句中添加一个左括号,从而开始一个新的分组。
$builder->orHavingGroupStart()
在查询的 HAVING 子句中添加一个左括号,并在其前面加上 OR,从而开始一个新的分组。
$builder->notHavingGroupStart()
在查询的 HAVING 子句中添加一个左括号,并在其前面加上 NOT,从而开始一个新的分组。
$builder->orNotHavingGroupStart()
在查询的 HAVING 子句中添加一个左括号,并在其前面加上 OR NOT,从而开始一个新的分组。
$builder->havingGroupEnd()
在查询的 HAVING 子句中添加一个右括号,从而结束当前分组。
插入数据
插入
$builder->insert()
根据您提供的数据生成一个插入字符串,并运行查询。您可以向方法传递一个 数组 或一个 对象。以下是一个使用数组的示例
<?php
use CodeIgniter\Database\RawSql;
$data = [
'id' => new RawSql('DEFAULT'),
'title' => 'My title',
'name' => 'My Name',
'date' => '2022-01-01',
'last_update' => new RawSql('CURRENT_TIMESTAMP()'),
];
$builder->insert($data);
/* Produces:
INSERT INTO mytable (id, title, name, date, last_update)
VALUES (DEFAULT, 'My title', 'My name', '2022-01-01', CURRENT_TIMESTAMP())
*/
第一个参数是一个关联数组,包含要插入的值。
注意
除了 RawSql
之外的所有值都会自动转义,从而生成更安全的查询。
警告
当您使用 RawSql
时,您必须手动转义数据。否则可能会导致 SQL 注入。
以下是一个使用对象的示例
<?php
namespace App\Libraries;
class MyClass
{
public $title = 'My Title';
public $content = 'My Content';
public $date = 'My Date';
}
<?php
use App\Libraries\MyClass;
$object = new MyClass();
$builder->insert($object);
// Produces: INSERT INTO mytable (title, content, date) VALUES ('My Title', 'My Content', 'My Date')
第一个参数是一个对象。
$builder->ignore()
根据您提供的数据生成一个插入忽略字符串,并运行查询。因此,如果具有相同主键的条目已经存在,则不会插入查询。您可以选择将一个**布尔值**传递给该方法。也可以用于**insertBatch**、**update** 和**delete**(在支持的情况下)。以下是一个使用上面示例数组的示例
<?php
$data = [
'title' => 'My title',
'name' => 'My Name',
'date' => 'My date',
];
$builder->ignore(true)->insert($data);
// Produces: INSERT OR IGNORE INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date')
$builder->getCompiledInsert()
编译插入查询,就像$builder->insert()
一样,但不会运行查询。此方法只是将 SQL 查询作为字符串返回。
示例
<?php
$data = [
'title' => 'My title',
'name' => 'My Name',
'date' => 'My date',
];
$sql = $builder->set($data)->getCompiledInsert();
echo $sql;
// Produces string: INSERT INTO mytable (`title`, `name`, `date`) VALUES ('My title', 'My name', 'My date')
第一个参数使您能够设置查询构建器查询是否将被重置(默认情况下将被重置 - 就像$builder->insert()
一样)
<?php
echo $builder->set('title', 'My Title')->getCompiledInsert(false);
// Produces string: INSERT INTO mytable (`title`) VALUES ('My Title')
echo $builder->set('content', 'My Content')->getCompiledInsert();
// Produces string: INSERT INTO mytable (`title`, `content`) VALUES ('My Title', 'My Content')
第二个查询之所以有效,是因为第一个参数被设置为false
。
注意
此方法不适用于批量插入。
insertBatch
$builder->insertBatch()
从数据插入
根据您提供的数据生成一个插入字符串,并运行查询。您可以向方法传递一个 数组 或一个 对象。以下是一个使用数组的示例
<?php
$data = [
[
'title' => 'My title',
'name' => 'My Name',
'date' => 'My date',
],
[
'title' => 'Another title',
'name' => 'Another Name',
'date' => 'Another date',
],
];
$builder->insertBatch($data);
/*
* Produces:
* INSERT INTO mytable (title, name, date)
* VALUES ('My title', 'My name', 'My date'),
* ('Another title', 'Another name', 'Another date')
*/
第一个参数是一个关联数组,包含要插入的值。
注意
除了 RawSql
之外的所有值都会自动转义,从而生成更安全的查询。
警告
当您使用 RawSql
时,您必须手动转义数据。否则可能会导致 SQL 注入。
从查询插入
您也可以从查询插入
<?php
use CodeIgniter\Database\RawSql;
$query = 'SELECT user2.name, user2.email, user2.country
FROM user2
LEFT JOIN user ON user.email = user2.email
WHERE user.email IS NULL';
$sql = $builder
->ignore(true)
->setQueryAsData(new RawSql($query), null, 'name, country, email')
->insertBatch();
/* MySQLi produces:
INSERT IGNORE INTO `db_user` (`name`, `country`, `email`)
SELECT user2.name, user2.email, user2.country
FROM user2
LEFT JOIN user ON user.email = user2.email
WHERE user.email IS NULL
*/
注意
setQueryAsData()
可从 v4.3.0 开始使用。
注意
需要将选择查询的列别名与目标表的列别名匹配。
Upserting Data
Upsert
$builder->upsert()
版本 4.3.0 中的新增功能。
根据您提供的数据生成一个 upsert 字符串,并运行查询。您可以向方法传递一个 **数组** 或一个 **对象**。默认情况下,约束将按顺序定义。主键将首先被选中,然后是唯一键。MySQL 默认情况下将使用任何约束。以下是一个使用数组的示例
<?php
$data = [
'email' => '[email protected]',
'name' => 'Ahmadinejad',
'country' => 'Iran',
];
$builder->upsert($data);
// MySQLi produces: INSERT INTO.. ON DUPLICATE KEY UPDATE..
// Postgre produces: INSERT INTO.. ON CONFLICT.. DO UPDATE..
// SQLite3 produces: INSERT INTO.. ON CONFLICT.. DO UPDATE..
// SQLSRV produces: MERGE INTO.. WHEN MATCHED THEN UPDATE.. WHEN NOT MATCHED THEN INSERT..
// OCI8 produces: MERGE INTO.. WHEN MATCHED THEN UPDATE.. WHEN NOT MATCHED THEN INSERT..
第一个参数是一个关联数组,包含要插入的值。
以下是一个使用对象的示例
<?php
namespace App\Libraries;
class MyClass
{
public $email = '[email protected]';
public $name = 'Ahmadinejad';
public $country = 'Iran';
}
<?php
use App\Libraries\MyClass;
$object = new MyClass();
$builder->upsert($object);
第一个参数是一个对象。
注意
所有值都会自动转义,生成更安全的查询。
$builder->getCompiledUpsert()
版本 4.3.0 中的新增功能。
编译 upsert 查询,就像 $builder->upsert()
一样,但不会 *运行* 查询。此方法只返回 SQL 查询作为字符串。
示例
<?php
$data = [
'email' => '[email protected]',
'name' => 'Ahmadinejad',
'country' => 'Iran',
];
$sql = $builder->setData($data)->getCompiledUpsert();
echo $sql;
/* MySQLi produces:
INSERT INTO `db_user` (`country`, `email`, `name`)
VALUES ('Iran','[email protected]','Ahmadinejad')
ON DUPLICATE KEY UPDATE
`country` = VALUES(`country`),
`email` = VALUES(`email`),
`name` = VALUES(`name`)
*/
注意
此方法不适用于批量 upsert。
upsertBatch
$builder->upsertBatch()
版本 4.3.0 中的新增功能。
从数据中 Upsert
根据您提供的数据生成一个 upsert 字符串,并运行查询。您可以向方法传递一个 **数组** 或一个 **对象**。默认情况下,约束将按顺序定义。主键将首先被选中,然后是唯一键。MySQL 默认情况下将使用任何约束。
以下是一个使用数组的示例
<?php
$data = [
[
'id' => 2,
'email' => '[email protected]',
'name' => 'Ahmadinejad',
'country' => 'Iran',
],
[
'id' => null,
'email' => '[email protected]',
'name' => 'Pedro',
'country' => 'El Salvador',
],
];
$builder->upsertBatch($data);
// MySQLi produces: INSERT INTO.. ON DUPLICATE KEY UPDATE..
// Postgre produces: INSERT INTO.. ON CONFLICT.. DO UPDATE..
// SQLite3 produces: INSERT INTO.. ON CONFLICT.. DO UPDATE..
// SQLSRV produces: MERGE INTO.. WHEN MATCHED THEN UPDATE.. WHEN NOT MATCHED THEN INSERT..
// OCI8 produces: MERGE INTO.. WHEN MATCHED THEN UPDATE.. WHEN NOT MATCHED THEN INSERT..
第一个参数是一个关联数组,包含要插入的值。
注意
所有值都会自动转义,生成更安全的查询。
从查询中 Upsert
您也可以从查询中 upsert
<?php
use CodeIgniter\Database\RawSql;
$query = $this->db->table('user2')
->select('user2.name, user2.email, user2.country')
->join('user', 'user.email = user2.email', 'left')
->where('user.email IS NULL');
$additionalUpdateField = ['updated_at' => new RawSql('CURRENT_TIMESTAMP')];
$sql = $builder->setQueryAsData($query)
->onConstraint('email')
->updateFields($additionalUpdateField, true)
->upsertBatch();
/* MySQLi produces:
INSERT INTO `db_user` (`country`, `email`, `name`)
SELECT user2.name, user2.email, user2.country
FROM user2
LEFT JOIN user ON user.email = user2.email
WHERE user.email IS NULL
ON DUPLICATE KEY UPDATE
`country` = VALUES(`country`),
`email` = VALUES(`email`),
`name` = VALUES(`name`),
`updated_at` = CURRENT_TIMESTAMP
*/
注意
从 v4.3.0 开始,可以使用 setQueryAsData()
、onConstraint()
和 updateFields()
方法。
注意
需要将选择查询的列别名与目标表的列别名匹配。
$builder->onConstraint()
版本 4.3.0 中的新增功能。
允许手动设置用于 upsert 的约束。这在 MySQL 中不起作用,因为 MySQL 默认情况下会检查所有约束。
<?php
$data = [
'id' => 2,
'email' => '[email protected]',
'name' => 'Ahmadinejad',
'country' => 'Iran',
];
$builder->onConstraint('email')->upsert($data);
/* Postgre produces:
INSERT INTO "db_user"("country", "email", "id", "name")
VALUES ('Iran','[email protected]',2,'Ahmadinejad')
ON CONFLICT("email")
DO UPDATE SET
"country" = "excluded"."country",
"id" = "excluded"."id",
"name" = "excluded"."name"
*/
此方法接受一个字符串或一个列数组。
$builder->updateFields()
版本 4.3.0 中的新增功能。
允许手动设置在执行 upsert 时要更新的字段。
<?php
$data = [
'id' => 2,
'email' => '[email protected]',
'name' => 'Ahmadinejad Zaghari',
'country' => 'Afghanistan',
];
$builder->updateFields('name, country')->setData($data, null, '_upsert')->upsert();
/* SQLSRV produces:
MERGE INTO "test"."dbo"."db_user"
USING (
VALUES ('Iran','[email protected]',2,'Ahmadinejad')
) "_upsert" ("country", "email", "id", "name")
ON ("test"."dbo"."db_user"."id" = "_upsert"."id")
WHEN MATCHED THEN UPDATE SET
"country" = "_upsert"."country",
"name" = "_upsert"."name"
WHEN NOT MATCHED THEN INSERT ("country", "email", "id", "name")
VALUES ("_upsert"."country", "_upsert"."email", "_upsert"."id", "_upsert"."name");
*/
此方法接受字符串、列数组或 RawSql。您还可以指定一个不在数据集中的额外列进行更新。这可以通过将第二个参数设置为 true
来实现。
<?php
use CodeIgniter\Database\RawSql;
$data = [
[
'id' => 2,
'email' => '[email protected]',
'name' => 'Ahmadinejad',
'country' => 'Iran',
],
[
'id' => null,
'email' => '[email protected]',
'name' => 'Pedro',
'country' => 'El Salvador',
],
];
$additionalUpdateField = ['updated_at' => new RawSql('CURRENT_TIMESTAMP')];
$sql = $builder->setData($data)->updateFields($additionalUpdateField, true)->upsertBatch();
/* MySQLi produces:
INSERT INTO `db_user` (`country`, `email`, `name`)
VALUES ('Iran','[email protected]','Ahmadinejad'),('El Salvador','[email protected]','Pedro')
ON DUPLICATE KEY UPDATE
`country` = VALUES(`country`),
`email` = VALUES(`email`),
`name` = VALUES(`name`),
`updated_at` = CURRENT_TIMESTAMP
*/
请注意,updated_at
字段不会被插入,而是在更新时使用。
更新数据
更新
$builder->replace()
此方法执行 REPLACE 语句,它基本上是 SQL 标准中用于(可选)DELETE + INSERT 的语句,使用主键和唯一键作为决定因素。在我们的例子中,它将免除您实现使用 select()
、update()
、delete()
和 insert()
的不同组合的复杂逻辑。
示例
<?php
$data = [
'title' => 'My title',
'name' => 'My Name',
'date' => 'My date',
];
$builder->replace($data);
// Executes: REPLACE INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date')
在上面的例子中,如果我们假设 title
字段是我们的主键,那么如果存在包含 My title
作为 title
值的行,该行将被删除,并用我们的新行数据替换。
也允许使用 set()
方法,并且所有值都会自动转义,就像使用 insert()
一样。
$builder->set()
此方法允许您为插入或更新设置值。
它可以用来代替直接将数据数组传递给 insert() 或 update() 方法。
<?php
$builder->set('name', $name);
$builder->insert();
// Produces: INSERT INTO mytable (`name`) VALUES ('{$name}')
如果您使用多个方法调用,它们将根据您是进行插入还是更新而被正确地组合起来。
<?php
$builder->set('name', $name);
$builder->set('title', $title);
$builder->set('status', $status);
$builder->insert();
set()
还接受一个可选的第三个参数 ($escape
),如果设置为 false
,则会阻止对值进行转义。为了说明区别,这里展示了 set()
在使用和不使用转义参数时的用法。
<?php
$builder->set('field', 'field+1', false);
$builder->where('id', 2);
$builder->update();
// gives UPDATE mytable SET field = field+1 WHERE `id` = 2
$builder->set('field', 'field+1');
$builder->where('id', 2);
$builder->update();
// gives UPDATE `mytable` SET `field` = 'field+1' WHERE `id` = 2
您也可以将关联数组传递给此方法
<?php
$array = [
'name' => $name,
'title' => $title,
'status' => $status,
];
$builder->set($array);
$builder->insert();
或一个对象
<?php
namespace App\Libraries;
class MyClass
{
public $title = 'My Title';
public $content = 'My Content';
public $date = 'My Date';
}
<?php
use App\Libraries\MyClass;
$object = new MyClass();
$builder->set($object);
$builder->insert();
$builder->update()
根据您提供的数据生成更新字符串并运行查询。您可以将一个数组或一个对象传递给该方法。以下是一个使用数组的示例
<?php
$data = [
'title' => $title,
'name' => $name,
'date' => $date,
];
$builder->where('id', $id);
$builder->update($data);
/*
* Produces:
* UPDATE mytable
* SET title = '{$title}', name = '{$name}', date = '{$date}'
* WHERE id = $id
*/
或者您可以提供一个对象
<?php
namespace App\Libraries;
class MyClass
{
public $title = 'My Title';
public $content = 'My Content';
public $date = 'My Date';
}
<?php
use App\Libraries\MyClass;
$object = new MyClass();
$builder->where('id', $id);
$builder->update($object);
/*
* Produces:
* UPDATE `mytable`
* SET `title` = '{$title}', `content` = '{$content}', `date` = '{$date}'
* WHERE id = `$id`
*/
注意
除了 RawSql
之外的所有值都会自动转义,从而生成更安全的查询。
警告
当您使用 RawSql
时,您必须手动转义数据。否则可能会导致 SQL 注入。
您会注意到使用了 $builder->where()
方法,使您能够设置WHERE 子句。您可以选择将此信息直接作为字符串传递到 update()
方法中
<?php
$builder->update($data, 'id = 4');
或作为数组
<?php
$builder->update($data, ['id' => $id]);
您也可以在执行更新时使用上面描述的 $builder->set()
方法。
$builder->getCompiledUpdate()
这与 $builder->getCompiledInsert()
的工作方式完全相同,只是它生成的是UPDATE SQL 字符串而不是INSERT SQL 字符串。
有关更多信息,请查看 $builder->getCompiledInsert() 的文档。
注意
此方法不适用于批量更新。
UpdateBatch
$builder->updateBatch()
注意
从 v4.3.0 开始,updateBatch()
的第二个参数 $index
已更改为 $constraints
。现在它接受数组、字符串或 RawSql
类型。
从数据更新
根据您提供的数据生成更新字符串并运行查询。您可以将一个数组或一个对象传递给该方法。以下是一个使用数组的示例
<?php
$data = [
[
'title' => 'Title 1',
'author' => 'Author 1',
'name' => 'Name 1',
'date' => 'Date 1',
],
[
'title' => 'Title 2',
'author' => 'Author 2',
'name' => 'Name 2',
'date' => 'Date 2',
],
];
$builder->updateBatch($data, ['title', 'author']);
/*
* Produces:
* UPDATE `mytable`
* INNER JOIN (
* SELECT 'Title 1' `title`, 'Author 1' `author`, 'Name 1' `name`, 'Date 1' `date` UNION ALL
* SELECT 'Title 2' `title`, 'Author 2' `author`, 'Name 2' `name`, 'Date 2' `date`
* ) `u`
* ON `mytable`.`title` = `u`.`title` AND `mytable`.`author` = `u`.`author`
* SET
* `mytable`.`title` = `u`.`title`,
* `mytable`.`name` = `u`.`name`,
* `mytable`.`date` = `u`.`date`
*/
第一个参数是值的关联数组,第二个参数是 where 键。
注意
从 v4.3.0 开始,生成的 SQL 结构已得到改进。
从 v4.3.0 版本开始,您也可以使用 onConstraint()
和 updateFields()
方法
<?php
use CodeIgniter\Database\RawSql;
$builder->setData($data)->onConstraint('title, author')->updateBatch();
// OR
$builder->setData($data, null, 'u')
->onConstraint(['`mytable`.`title`' => '`u`.`title`', 'author' => new RawSql('`u`.`author`')])
->updateBatch();
// OR
foreach ($data as $row) {
$builder->setData($row);
}
$builder->onConstraint('title, author')->updateBatch();
// OR
$builder->setData($data, true, 'u')
->onConstraint(new RawSql('`mytable`.`title` = `u`.`title` AND `mytable`.`author` = `u`.`author`'))
->updateFields(['last_update' => new RawSql('CURRENT_TIMESTAMP()')], true)
->updateBatch();
/*
* Produces:
* UPDATE `mytable`
* INNER JOIN (
* SELECT 'Title 1' `title`, 'Author 1' `author`, 'Name 1' `name`, 'Date 1' `date` UNION ALL
* SELECT 'Title 2' `title`, 'Author 2' `author`, 'Name 2' `name`, 'Date 2' `date`
* ) `u`
* ON `mytable`.`title` = `u`.`title` AND `mytable`.`author` = `u`.`author`
* SET
* `mytable`.`title` = `u`.`title`,
* `mytable`.`name` = `u`.`name`,
* `mytable`.`date` = `u`.`date`,
* `mytable`.`last_update` = CURRENT_TIMESTAMP() // this only applies to the last scenario
*/
注意
除了 RawSql
之外的所有值都会自动转义,从而生成更安全的查询。
警告
当您使用 RawSql
时,您必须手动转义数据。否则可能会导致 SQL 注入。
注意
affectedRows()
方法无法提供正确的结果,因为它的工作原理决定了这一点。相反,updateBatch()
方法会返回受影响的行数。
从查询更新
从 v4.3.0 版本开始,您也可以使用 setQueryAsData()
方法从查询中更新数据。
<?php
use CodeIgniter\Database\RawSql;
$query = $this->db->table('user2')
->select('user2.name, user2.email, user2.country')
->join('user', 'user.email = user2.email', 'inner')
->where('user2.country', 'US');
$additionalUpdateField = ['updated_at' => new RawSql('CURRENT_TIMESTAMP')];
$sql = $builder->table('user')
->setQueryAsData($query, null, 'u')
->onConstraint('email')
->updateFields($additionalUpdateField, true)
->updateBatch();
/*
* Produces:
* UPDATE `user`
* INNER JOIN (
* SELECT user2.name, user2.email, user2.country
* FROM user2
* INNER JOIN user ON user.email = user2.email
* WHERE user2.country = 'US'
* ) `u`
* ON `user`.`email` = `u`.`email`
* SET
* `mytable`.`name` = `u`.`name`,
* `mytable`.`email` = `u`.`email`,
* `mytable`.`country` = `u`.`country`,
* `mytable`.`updated_at` = CURRENT_TIMESTAMP()
*/
注意
需要将选择查询的列别名与目标表的列别名匹配。
删除数据
删除
$builder->delete()
生成一个 DELETE SQL 语句并执行查询。
<?php
$builder->delete(['id' => $id]);
// Produces: DELETE FROM mytable WHERE id = $id
第一个参数是 where 子句。您也可以使用 where()
或 orWhere()
方法,而不是将数据传递给方法的第一个参数。
<?php
$builder->where('id', $id);
$builder->delete();
/*
* Produces:
* DELETE FROM mytable
* WHERE id = $id
*/
如果您想删除表中的所有数据,可以使用 truncate()
方法或 emptyTable()
方法。
$builder->getCompiledDelete()
它的工作方式与 $builder->getCompiledInsert()
完全相同,只是它生成的是 DELETE SQL 语句,而不是 INSERT SQL 语句。
有关更多信息,请查看 $builder->getCompiledInsert() 的文档。
批量删除
$builder->deleteBatch()
版本 4.3.0 中的新增功能。
从数据中删除
根据一组数据生成一个批量的 DELETE 语句。
<?php
$data = [
[
'order' => 48372,
'line' => 3,
'product' => 'Keyboard',
'qty' => 1,
],
[
'order' => 48372,
'line' => 4,
'product' => 'Mouse',
'qty' => 1,
],
[
'order' => 48372,
'line' => 5,
'product' => 'Monitor',
'qty' => 2,
],
];
$builder->setData($data, true, 'del')
->onConstraint('order, line')
->where('del.qty >', 1)
->deleteBatch();
/*
* MySQL Produces:
* DELETE `order_line` FROM `order_line`
* INNER JOIN (
* SELECT 3 `line`, 48372 `order`, 'Keyboard' `product`, 1 `qty` UNION ALL
* SELECT 4 `line`, 48372 `order`, 'Mouse' `product`, 1 `qty` UNION ALL
* SELECT 5 `line`, 48372 `order`, 'Monitor' `product`, 2 `qty`
* ) `del`
* ON `order_line`.`order` = `del`.`order` AND `order_line`.`line` = `del`.`line`
* WHERE `del`.`qty` > 1
*/
当删除具有复合主键的表中的数据时,此方法可能特别有用。
注意
SQLite3 不支持使用 where()
。
从查询中删除
您也可以从查询中删除
<?php
use CodeIgniter\Database\RawSql;
$query = $this->db->table('user2')->select('email, name, country')->where('country', 'Greece');
$this->db->table('user')
->setQueryAsData($query, 'alias')
->onConstraint('email')
->where('alias.name = user.name')
->deleteBatch();
/* MySQLi produces:
DELETE `user` FROM `user`
INNER JOIN (
SELECT `email`, `name`, `country`
FROM `user2`
WHERE `country` = 'Greece') `alias`
ON `user`.`email` = `alias`.`email`
WHERE `alias`.`name` = `user`.`name`
*/
$builder->emptyTable()
生成一个 DELETE SQL 字符串并运行查询
<?php
$builder->emptyTable('mytable');
// Produces: DELETE FROM mytable
$builder->truncate()
生成一个 TRUNCATE SQL 字符串并运行查询。
<?php
$builder->truncate();
/*
* Produce:
* TRUNCATE mytable
*/
注意
如果 TRUNCATE 命令不可用,truncate()
将执行为“DELETE FROM table”。
条件语句
当
$builder->when()
版本 4.3.0 中的新增功能。
这允许根据条件修改查询,而不会中断查询构建器链。第一个参数是条件,它应该计算为布尔值。第二个参数是一个可调用对象,当条件为真时将运行。
例如,您可能只想根据 HTTP 请求中发送的值应用给定的 WHERE 语句
<?php
$status = service('request')->getPost('status');
$users = $this->db->table('users')
->when($status, static function ($query, $status) {
$query->where('status', $status);
})
->get();
由于条件计算为 true
,因此将调用可调用对象。条件中设置的值将作为第二个参数传递给可调用对象,以便它可以在查询中使用。
有时您可能希望在条件计算为假时应用不同的语句。这可以通过提供第二个闭包来实现
<?php
$onlyInactive = service('request')->getPost('return_inactive');
$users = $this->db->table('users')
->when($onlyInactive, static function ($query, $onlyInactive) {
$query->where('status', 'inactive');
}, static function ($query) {
$query->where('status', 'active');
})
->get();
当不
$builder->whenNot()
版本 4.3.0 中的新增功能。
这与 $builder->when()
的工作方式完全相同,只是它只会在条件计算为 false
时运行可调用对象,而不是像 when()
那样计算为 true
。
<?php
$status = service('request')->getPost('status');
$users = $this->db->table('users')
->whenNot($status, static function ($query, $status) {
$query->where('active', 0);
})
->get();
方法链
方法链允许您通过连接多个方法来简化语法。考虑以下示例
<?php
$query = $builder->select('title')
->where('id', $id)
->limit(10, 20)
->get();
重置查询构建器
ResetQuery
$builder->resetQuery()
重置查询构建器允许您从头开始构建查询,而无需先使用诸如 $builder->get()
或 $builder->insert()
之类的方法执行查询。
这在您使用查询构建器生成 SQL(例如,$builder->getCompiledSelect()
)但随后选择运行查询的情况下很有用。
<?php
// Note that the parameter of the `getCompiledSelect()` method is false
$sql = $builder->select(['field1', 'field2'])
->where('field3', 5)
->getCompiledSelect(false);
// ...
// Do something crazy with the SQL code... like add it to a cron script for
// later execution or something...
// ...
$data = $builder->get()->getResultArray();
/*
* Would execute and return an array of results of the following query:
* SELECT field1, field2 FROM mytable WHERE field3 = 5;
*/
类引用
- class CodeIgniter\Database\BaseBuilder
- db()
- 返回:
正在使用的数据库连接
- 返回类型:
ConnectionInterface
从
$db
返回当前的数据库连接。对于访问ConnectionInterface
方法(这些方法不能直接用于查询构建器)很有用,例如insertID()
或errors()
。
- resetQuery()
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
重置当前查询构建器状态。当您想要构建一个可以在特定条件下取消的查询时很有用。
- countAllResults([$reset = true])
- 参数:
$reset (
bool
) – 是否重置 SELECT 的值
- 返回:
查询结果中的行数
- 返回类型:
int
生成一个平台特定的查询字符串,用于计算 Query Builder 查询返回的所有记录。
- countAll([$reset = true])
- 参数:
$reset (
bool
) – 是否重置 SELECT 的值
- 返回:
查询结果中的行数
- 返回类型:
int
生成一个平台特定的查询字符串,用于计算特定表中的所有记录。
- get([$limit = null[, $offset = null[, $reset = true]]]])
- 参数:
$limit (
int
) – LIMIT 子句$offset (
int
) – OFFSET 子句$reset (
bool
) – 我们是否要清除查询构建器值?
- 返回:
\CodeIgniter\Database\ResultInterface
实例(方法链)- 返回类型:
\CodeIgniter\Database\ResultInterface
编译并运行基于已调用的 Query Builder 方法的
SELECT
语句。
- getWhere([$where = null[, $limit = null[, $offset = null[, $reset = true]]]]])
- 参数:
$where (
string
) – WHERE 子句$limit (
int
) – LIMIT 子句$offset (
int
) – OFFSET 子句$reset (
bool
) – 我们是否要清除查询构建器值?
- 返回:
\CodeIgniter\Database\ResultInterface
实例(方法链)- 返回类型:
\CodeIgniter\Database\ResultInterface
与
get()
相同,但还允许直接添加 WHERE。
- select([$select = '*'[, $escape = null]])
- 参数:
$select (
array|RawSql|string
) – 查询的 SELECT 部分$escape (
bool
) – 是否转义值和标识符
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
向查询添加
SELECT
子句。
- selectAvg([$select = ''[, $alias = '']])
- 参数:
$select (
string
) – 要计算平均值的字段$alias (
string
) – 结果值名称的别名
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
向查询添加
SELECT AVG(field)
子句。
- selectMax([$select = ''[, $alias = '']])
- 参数:
$select (
string
) – 要计算最大值的字段$alias (
string
) – 结果值名称的别名
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
向查询添加
SELECT MAX(field)
子句。
- selectMin([$select = ''[, $alias = '']])
- 参数:
$select (
string
) – 要计算最小值的字段$alias (
string
) – 结果值名称的别名
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
在查询中添加
SELECT MIN(field)
子句。
- selectSum([$select = ''[, $alias = '']])
- 参数:
$select (
string
) – 要计算总和的字段$alias (
string
) – 结果值名称的别名
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
在查询中添加
SELECT SUM(field)
子句。
- selectCount([$select = ''[, $alias = '']])
- 参数:
$select (
string
) – 要计算平均值的字段$alias (
string
) – 结果值名称的别名
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
在查询中添加
SELECT COUNT(field)
子句。
- selectSubquery(BaseBuilder $subquery, string $as)
- 参数:
$subquery (
string
) – BaseBuilder 实例$as (
string
) – 结果值名称的别名
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
在选择中添加子查询
- distinct([$val = true])
- 参数:
$val (
bool
) – “distinct” 标志的期望值
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
设置一个标志,告诉查询构建器在查询的
SELECT
部分添加DISTINCT
子句。
- from($from[, $overwrite = false])
- 参数:
$from (
mixed
) – 表名;字符串或数组$overwrite (
bool
) – 是否移除第一个存在的表?
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
指定查询的
FROM
子句。
- fromSubquery($from, $alias)
- 参数:
$from (
BaseBuilder
) – BaseBuilder 类的实例$alias (
string
) – 子查询别名
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
使用子查询指定查询的
FROM
子句。
- setQueryAsData($query[, $alias[, $columns = null]])
版本 4.3.0 中的新增功能。
- 参数:
$query (
BaseBuilder|RawSql
) – BaseBuilder 或 RawSql 的实例$alias (
string|null
) – 查询的别名$columns (
array|string|null
) – 查询中列的数组或逗号分隔字符串
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
将查询设置为
insertBatch()
、updateBatch()
、upsertBatch()
的数据源。如果$columns
为空,则将运行查询以生成列名。
- join($table, $cond[, $type = ''[, $escape = null]])
- 参数:
$table (
string
) – 要连接的表名$cond (
string
) – JOIN ON 条件$type (
string
) – JOIN 类型$escape (
bool
) – 是否转义值和标识符
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
向查询添加
JOIN
子句。
- where($key[, $value = null[, $escape = null]])
- 参数:
$key (
array|RawSql|string
) – 要比较的字段名,或关联数组$value (
mixed
) – 如果是单个键,则与该值进行比较$escape (
bool
) – 是否转义值和标识符
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
生成查询的
WHERE
部分。用AND
分隔多个调用。
- orWhere($key[, $value = null[, $escape = null]])
- 参数:
$key (
mixed
) – 要比较的字段名,或关联数组$value (
mixed
) – 如果是单个键,则与该值进行比较$escape (
bool
) – 是否转义值和标识符
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
生成查询的
WHERE
部分。用OR
分隔多个调用。
- orWhereIn([$key = null[, $values = null[, $escape = null]]])
- 参数:
$key (
string
) – 要搜索的字段$values (
array|BaseBulder|Closure
) – 目标值的数组,或用于子查询的匿名函数$escape (
bool
) – 是否转义值和标识符
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
生成一个
WHERE
字段IN('item', 'item')
SQL 查询,如果需要,则用OR
连接。
- orWhereNotIn([$key = null[, $values = null[, $escape = null]]])
- 参数:
$key (
string
) – 要搜索的字段$values (
array|BaseBulder|Closure
) – 目标值的数组,或用于子查询的匿名函数$escape (
bool
) – 是否转义值和标识符
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
生成一个
WHERE
字段NOT IN('item', 'item')
SQL 查询,如果需要,则用OR
连接。
- whereIn([$key = null[, $values = null[, $escape = null]]])
- 参数:
$key (
string
) – 要检查的字段的名称$values (
array|BaseBulder|Closure
) – 目标值的数组,或用于子查询的匿名函数$escape (
bool
) – 是否转义值和标识符
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
生成一个
WHERE
字段IN('item', 'item')
SQL 查询,如果需要,则用AND
连接。
- whereNotIn([$key = null[, $values = null[, $escape = null]]])
- 参数:
$key (
string
) – 要检查的字段的名称$values (
array|BaseBulder|Closure
) – 目标值的数组,或用于子查询的匿名函数$escape (
bool
) – 是否转义值和标识符
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
生成一个
WHERE
字段NOT IN('item', 'item')
SQL 查询,如果需要,则用AND
连接。
- groupStart()
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
使用
AND
运算符开始一个分组表达式,用于表达式内的条件。
- orGroupStart()
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
使用
OR
运算符开始一个分组表达式,用于表达式内的条件。
- notGroupStart()
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
使用
AND NOT
运算符开始一个分组表达式,用于表达式内的条件。
- orNotGroupStart()
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
使用
OR NOT
运算符开始一个分组表达式,用于表达式内的条件。
- groupEnd()
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
结束一个分组表达式。
- like($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
- 参数:
$field (
array|RawSql|string
) – 字段名称$match (
string
) – 要匹配的文本部分$side (
string
) – 将 ‘%’ 通配符放在表达式的哪一边$escape (
bool
) – 是否转义值和标识符$insensitiveSearch (
bool
) – 是否强制不区分大小写的搜索
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
向查询添加
LIKE
子句,使用AND
分隔多个调用。
- orLike($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
- 参数:
$field (
string
) – 字段名称$match (
string
) – 要匹配的文本部分$side (
string
) – 将 ‘%’ 通配符放在表达式的哪一边$escape (
bool
) – 是否转义值和标识符$insensitiveSearch (
bool
) – 是否强制不区分大小写的搜索
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
在查询中添加
LIKE
子句,使用OR
分隔多个类。
- notLike($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
- 参数:
$field (
string
) – 字段名称$match (
string
) – 要匹配的文本部分$side (
string
) – 将 ‘%’ 通配符放在表达式的哪一边$escape (
bool
) – 是否转义值和标识符$insensitiveSearch (
bool
) – 是否强制不区分大小写的搜索
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
在查询中添加
NOT LIKE
子句,使用AND
分隔多个调用。
- orNotLike($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
- 参数:
$field (
string
) – 字段名称$match (
string
) – 要匹配的文本部分$side (
string
) – 将 ‘%’ 通配符放在表达式的哪一边$escape (
bool
) – 是否转义值和标识符$insensitiveSearch (
bool
) – 是否强制不区分大小写的搜索
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
在查询中添加
NOT LIKE
子句,使用OR
分隔多个调用。
- having($key[, $value = null[, $escape = null]])
- 参数:
$key (
mixed
) – 标识符(字符串)或字段/值对的关联数组$value (
string
) – 如果 $key 是标识符,则查找的值$escape (
string
) – 是否对值和标识符进行转义
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
向查询添加
HAVING
子句,用AND
分隔多个调用。
- orHaving($key[, $value = null[, $escape = null]])
- 参数:
$key (
mixed
) – 标识符(字符串)或字段/值对的关联数组$value (
string
) – 如果 $key 是标识符,则查找的值$escape (
string
) – 是否对值和标识符进行转义
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
向查询添加
HAVING
子句,用OR
分隔多个调用。
- orHavingIn([$key = null[, $values = null[, $escape = null]]])
- 参数:
$key (
string
) – 要搜索的字段$values (
array|BaseBulder|Closure
) – 目标值的数组,或用于子查询的匿名函数$escape (
bool
) – 是否转义值和标识符
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
生成一个
HAVING
字段 IN(‘item’, ‘item’) SQL 查询,如果合适,则用OR
连接。
- orHavingNotIn([$key = null[, $values = null[, $escape = null]]])
- 参数:
$key (
string
) – 要搜索的字段$values (
array|BaseBulder|Closure
) – 目标值的数组,或用于子查询的匿名函数$escape (
bool
) – 是否转义值和标识符
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
生成一个
HAVING
字段NOT IN('item', 'item')
SQL 查询,如果合适,则用OR
连接。
- havingIn([$key = null[, $values = null[, $escape = null]]])
- 参数:
$key (
string
) – 要检查的字段的名称$values (
array|BaseBulder|Closure
) – 目标值的数组,或用于子查询的匿名函数$escape (
bool
) – 是否转义值和标识符
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
生成一个
HAVING
字段IN('item', 'item')
SQL 查询,如果合适则用AND
连接。
- havingNotIn([$key = null[, $values = null[, $escape = null]]])
- 参数:
$key (
string
) – 要检查的字段的名称$values (
array|BaseBulder|Closure
) – 目标值的数组,或用于子查询的匿名函数$escape (
bool
) – 是否转义值和标识符$insensitiveSearch (
bool
) – 是否强制不区分大小写的搜索
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
生成一个
HAVING
字段NOT IN('item', 'item')
SQL 查询,如果合适则用AND
连接。
- havingLike($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
- 参数:
$field (
string
) – 字段名称$match (
string
) – 要匹配的文本部分$side (
string
) – 将 ‘%’ 通配符放在表达式的哪一边$escape (
bool
) – 是否转义值和标识符$insensitiveSearch (
bool
) – 是否强制不区分大小写的搜索
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
向查询的
HAVING
部分添加LIKE
子句,用AND
分隔多个调用。
- orHavingLike($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
- 参数:
$field (
string
) – 字段名称$match (
string
) – 要匹配的文本部分$side (
string
) – 将 ‘%’ 通配符放在表达式的哪一边$escape (
bool
) – 是否转义值和标识符$insensitiveSearch (
bool
) – 是否强制不区分大小写的搜索
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
在查询的
HAVING
部分添加LIKE
子句,用OR
分隔多个类。
- notHavingLike($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
- 参数:
$field (
string
) – 字段名称$match (
string
) – 要匹配的文本部分$side (
string
) – 将 ‘%’ 通配符放在表达式的哪一边$escape (
bool
) – 是否转义值和标识符$insensitiveSearch (
bool
) – 是否强制不区分大小写的搜索
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
在查询的
HAVING
部分添加NOT LIKE
子句,用AND
分隔多个调用。
- orNotHavingLike($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
- 参数:
$field (
string
) – 字段名称$match (
string
) – 要匹配的文本部分$side (
string
) – 将 ‘%’ 通配符放在表达式的哪一边$escape (
bool
) – 是否转义值和标识符
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
在查询的
HAVING
部分添加NOT LIKE
子句,用OR
分隔多个调用。
- havingGroupStart()
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
为
HAVING
子句开始一个分组表达式,使用AND
来连接其中的条件。
- orHavingGroupStart()
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
为
HAVING
子句开始一个分组表达式,使用OR
来连接其中的条件。
- notHavingGroupStart()
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
为
HAVING
子句开始一个分组表达式,使用AND NOT
来连接其中的条件。
- orNotHavingGroupStart()
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
为
HAVING
子句开始一个分组表达式,使用OR NOT
来连接其中的条件。
- havingGroupEnd()
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
结束
HAVING
子句的分组表达式。
- groupBy($by[, $escape = null])
- 参数:
$by (
mixed
) – 要分组的字段;字符串或数组
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
向查询添加
GROUP BY
子句。
- orderBy($orderby[, $direction = ''[, $escape = null]])
- 参数:
$orderby (
string
) – 要排序的字段$direction (
string
) – 请求的排序方式 - ASC、DESC 或随机$escape (
bool
) – 是否转义值和标识符
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
向查询添加
ORDER BY
子句。
- limit($value[, $offset = 0])
- 参数:
$value (
int
) – 要限制的结果行数$offset (
int
) – 要跳过的行数
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
向查询添加
LIMIT
和OFFSET
子句。
- offset($offset)
- 参数:
$offset (
int
) – 要跳过的行数
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
向查询添加
OFFSET
子句。
- union($union)
- 参数:
$union (
BaseBulder|Closure
) – 并集查询
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
添加
UNION
子句。
- unionAll($union)
- 参数:
$union (
BaseBulder|Closure
) – 并集查询
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
添加
UNION ALL
子句。
- set($key[, $value = ''[, $escape = null]])
- 参数:
$key (
mixed
) – 字段名,或字段/值对的数组$value (
mixed
) – 字段值,如果 $key 是单个字段$escape (
bool
) – 是否转义值
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
添加字段/值对,以便稍后传递给
insert()
、update()
或replace()
。
- insert([$set = null[, $escape = null]])
- 参数:
$set (
array
) – 字段/值对的关联数组$escape (
bool
) – 是否转义值
- 返回:
成功时为
true
,失败时为false
- 返回类型:
bool
编译并执行一个
INSERT
语句。
- insertBatch([$set = null[, $escape = null[, $batch_size = 100]]])
- 参数:
$set (
array
) – 要插入的数据$escape (
bool
) – 是否转义值$batch_size (
int
) – 每次插入的行数
- 返回:
插入的行数或失败时为
false
- 返回类型:
int|false
编译并执行批量的
INSERT
语句。注意
当提供超过
$batch_size
行时,将执行多个INSERT
查询,每个查询尝试插入最多$batch_size
行。
- setInsertBatch($key[, $value = ''[, $escape = null]])
自版本 4.3.0 起已弃用: 请使用
CodeIgniter\Database\BaseBuilder::setData()
代替。- 参数:
$key (
mixed
) – 字段名或字段/值对的数组$value (
string
) – 字段值,如果 $key 是单个字段$escape (
bool
) – 是否转义值
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
添加字段/值对,以便稍后通过
insertBatch()
插入到表中。重要
此方法已弃用。它将在未来的版本中被移除。
- upsert([$set = null[, $escape = null]])
- 参数:
$set (
array
) – 字段/值对的关联数组$escape (
bool
) – 是否转义值
- 返回:
成功时为
true
,失败时为false
- 返回类型:
bool
编译并执行一个
UPSERT
语句。
- upsertBatch([$set = null[, $escape = null[, $batch_size = 100]]])
- 参数:
$set (
array
) – 要 upsert 的数据$escape (
bool
) – 是否转义值$batch_size (
int
) – 每次 upsert 的行数
- 返回:
已 upsert 的行数,或在失败时为
false
- 返回类型:
int|false
编译并执行批量
UPSERT
语句。注意
MySQL 使用
ON DUPLICATE KEY UPDATE
,每行的受影响行数为 1(如果该行作为新行插入),2(如果更新了现有行),以及 0(如果现有行设置为其当前值)。注意
当提供超过
$batch_size
行时,将执行多个UPSERT
查询,每个查询尝试 upsert 最多$batch_size
行。
- update([$set = null[, $where = null[, $limit = null]]])
- 参数:
$set (
array
) – 字段/值对的关联数组$where (
string
) – WHERE 子句$limit (
int
) – LIMIT 子句
- 返回:
成功时为
true
,失败时为false
- 返回类型:
bool
编译并执行一个
UPDATE
语句。
- updateBatch([$set = null[, $constraints = null[, $batchSize = 100]]])
- 参数:
$set (
array|object|null
) – 字段名称或字段/值对的关联数组$constraints (
array|RawSql|string|null
) – 用作更新键的字段或字段。$batchSize (
int
) – 单个查询中分组的条件数量
- 返回:
更新的行数或在失败时为
false
- 返回类型:
int|false
注意
从 v4.3.0 开始,参数
$set
和$constraints
的类型已更改。编译并执行批处理
UPDATE
语句。$constraints
参数接受以逗号分隔的列字符串、数组、关联数组或RawSql
。注意
当提供超过
$batchSize
个字段/值对时,将执行多个查询,每个查询处理最多$batchSize
个字段/值对。如果我们将$batchSize
设置为 0,那么所有字段/值对将在一个查询中执行。
- updateFields($set[, $addToDefault = false[, $ignore = null]])
版本 4.3.0 中的新增功能。
- 参数:
$set (
mixed
) – 列行或行数组,行是数组或对象$addToDefault (
bool
) – 添加除数据集中的列之外的附加列$ignore (
bool
) – 从 $set 中忽略的列数组
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
与
updateBatch()
和upsertBatch()
方法一起使用。这定义了将要更新的字段。
- onConstraint($set)
版本 4.3.0 中的新增功能。
- 参数:
$set (
mixed
) – 用作键或约束的一组字段或字段
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
与
updateBatch()
和upsertBatch()
方法一起使用。它接受以逗号分隔的列字符串、数组、关联数组或 RawSql。
- setData($set[, $escape = null[, $alias = '']])
版本 4.3.0 中的新增功能。
- 参数:
$set (
mixed
) – 列行或行数组,行是数组或对象$escape (
bool
) – 是否转义值$alias (
bool
) – 数据集的表别名
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
用于
*Batch()
方法为插入、更新、upsert 设置数据。
- setUpdateBatch($key[, $value = ''[, $escape = null]])
自版本 4.3.0 起已弃用: 请使用
CodeIgniter\Database\BaseBuilder::setData()
代替。- 参数:
$key (
mixed
) – 字段名或字段/值对的数组$value (
string
) – 字段值,如果 $key 是单个字段$escape (
bool
) – 是否转义值
- 返回:
BaseBuilder
实例(方法链)- 返回类型:
BaseBuilder
添加字段/值对,以便稍后通过
updateBatch()
在表中更新。重要
此方法已弃用。它将在未来的版本中被移除。
- replace([$set = null])
- 参数:
$set (
array
) – 字段/值对的关联数组
- 返回:
成功时为
true
,失败时为false
- 返回类型:
bool
编译并执行
REPLACE
语句。
- delete([$where = ''[, $limit = null[, $reset_data = true]]])
- 参数:
$where (
string
) – WHERE 子句$limit (
int
) – LIMIT 子句$reset_data (
bool
) – 重置查询“写入”子句,设置为 true
- 返回:
BaseBuilder
实例(方法链)或失败时返回false
- 返回类型:
BaseBuilder|false
编译并执行
DELETE
查询。
- deleteBatch([$set = null[, $constraints = null[, $batchSize = 100]]])
- 参数:
$set (
array|object|null
) – 字段名称或字段/值对的关联数组$constraints (
array|RawSql|string|null
) – 用作删除键的字段或字段。$batchSize (
int
) – 单个查询中分组的条件数量
- 返回:
删除的行数或失败时返回
false
- 返回类型:
int|false
编译并执行批处理
DELETE
查询。
- increment($column[, $value = 1])
- 参数:
$column (
string
) – 要递增的列的名称$value (
int
) – 要在列中递增的量
将字段的值增加指定数量。如果字段不是数字字段,例如
VARCHAR
,它可能会被替换为$value
。
- decrement($column[, $value = 1])
- 参数:
$column (
string
) – 要递减的列的名称$value (
int
) – 要在列中递减的量
将字段的值减少指定数量。如果字段不是数字字段,例如
VARCHAR
,它可能会被替换为$value
。
- truncate()
- 返回:
true
表示成功,false
表示失败,测试模式下返回字符串- 返回类型:
bool|string
对表执行
TRUNCATE
语句。注意
如果使用的数据库平台不支持
TRUNCATE
,则会使用DELETE
语句代替。
- emptyTable()
- 返回:
成功时为
true
,失败时为false
- 返回类型:
bool
使用
DELETE
语句从表中删除所有记录。
- getCompiledSelect([$reset = true])
- 参数:
$reset (
bool
) – 是否重置当前 QB 值
- 返回:
编译后的 SQL 语句,以字符串形式表示
- 返回类型:
string
编译
SELECT
语句并将其作为字符串返回。
- getCompiledInsert([$reset = true])
- 参数:
$reset (
bool
) – 是否重置当前 QB 值
- 返回:
编译后的 SQL 语句,以字符串形式表示
- 返回类型:
string
编译
INSERT
语句并将其作为字符串返回。
- getCompiledUpdate([$reset = true])
- 参数:
$reset (
bool
) – 是否重置当前 QB 值
- 返回:
编译后的 SQL 语句,以字符串形式表示
- 返回类型:
string
编译一个
UPDATE
语句并将其作为字符串返回。
- getCompiledDelete([$reset = true])
- 参数:
$reset (
bool
) – 是否重置当前 QB 值
- 返回:
编译后的 SQL 语句,以字符串形式表示
- 返回类型:
string
编译一个
DELETE
语句并将其作为字符串返回。