查询构建器

最后更新: 2026-01-27 11:02:47

查询构建器

查询构建器提供了流畅、直观的接口来构建和执行数据库查询。它使用参数绑定来防止 SQL 注入,并支持所有常见的数据库操作。

基础查询

获取查询构建器

use function db;

// 获取查询构建器实例 $query = db('users');

// 指定连接 $query = db('users', 'mysql');

SELECT 查询

// 查询所有字段
$users = db('users')->get();

// 查询指定字段 $users = db('users') ->select(['id', 'name', 'email']) ->get();

// 查询单个字段 $names = db('users') ->select('name') ->get();

获取单条记录

// 获取第一条记录
$user = db('users')->first();

// 根据 ID 查找 $user = db('users')->where('id', 1)->first();

// 查找或失败(找不到时抛出异常) $user = db('users')->where('id', 999)->firstOrFail();

获取单个值

// 获取单个字段值
$name = db('users')
    ->where('id', 1)
    ->value('name');

// 获取单个标量值(COUNT, MAX, MIN 等) $count = db('users')->count(); $maxId = db('users')->max('id'); $minId = db('users')->min('id'); $avgAge = db('users')->avg('age'); $sumScore = db('users')->sum('score');

判断记录是否存在

$exists = db('users')->where('email', 'user@example.com')->exists();

WHERE 条件

基本 WHERE

// 等于
$users = db('users')->where('status', 'active')->get();

// 不等于 $users = db('users')->where('status', '!=', 'inactive')->get();

// 大于/小于 $users = db('users')->where('age', '>', 18)->get(); $users = db('users')->where('age', '<', 65)->get(); $users = db('users')->where('age', '>=', 18)->get(); $users = db('users')->where('age', '<=', 65)->get();

WHERE IN / NOT IN

// WHERE IN
$users = db('users')
    ->whereIn('id', [1, 2, 3, 4, 5])
    ->get();

// WHERE NOT IN $users = db('users') ->whereNotIn('id', [1, 2, 3]) ->get();

WHERE NULL / NOT NULL

// WHERE IS NULL
$users = db('users')
    ->whereNull('deleted_at')
    ->get();

// WHERE IS NOT NULL $users = db('users') ->whereNotNull('email') ->get();

WHERE LIKE

// LIKE 查询
$users = db('users')
    ->where('name', 'LIKE', '%john%')
    ->get();

// 开头匹配 $users = db('users') ->where('email', 'LIKE', 'admin@%') ->get();

// 结尾匹配 $users = db('users') ->where('name', 'LIKE', '%com') ->get();

WHERE BETWEEN

$users = db('users')
    ->whereBetween('age', [18, 65])
    ->get();

// NOT BETWEEN $users = db('users') ->whereNotBetween('age', [18, 65]) ->get();

多个 WHERE 条件

// AND 条件
$users = db('users')
    ->where('status', 'active')
    ->where('age', '>', 18)
    ->get();

// OR 条件 $users = db('users') ->where('status', 'active') ->orWhere('status', 'pending') ->get();

嵌套 WHERE

$users = db('users')
    ->where('status', 'active')
    ->where(function($query) {
        $query->where('age', '>', 18)
              ->orWhere('verified', true);
    })
    ->get();

// 生成的 SQL: // SELECT * FROM users // WHERE status = 'active' // AND (age > 18 OR verified = 1)

WHERE 日期

// 日期等于
$users = db('users')
    ->whereDate('created_at', '2024-01-01')
    ->get();

// 年月匹配 $users = db('users') ->whereYear('created_at', 2024) ->whereMonth('created_at', 1) ->get();

// 日期范围 $users = db('users') ->whereBetween('created_at', ['2024-01-01', '2024-12-31']) ->get();

JOIN 查询

INNER JOIN

$users = db('users')
    ->join('profiles', 'users.id', '=', 'profiles.user_id')
    ->select('users.*', 'profiles.bio', 'profiles.avatar')
    ->get();

LEFT JOIN

$users = db('users')
    ->leftJoin('profiles', 'users.id', '=', 'profiles.user_id')
    ->select('users.*', 'profiles.bio')
    ->get();

RIGHT JOIN

$users = db('users')
    ->rightJoin('profiles', 'users.id', '=', 'profiles.user_id')
    ->get();

多个 JOIN

$posts = db('posts')
    ->join('users', 'posts.user_id', '=', 'users.id')
    ->leftJoin('categories', 'posts.category_id', '=', 'categories.id')
    ->select('posts.*', 'users.name as author', 'categories.name as category')
    ->get();

复杂 JOIN 条件

$users = db('users')
    ->join('profiles', function($join) {
        $join->on('users.id', '=', 'profiles.user_id')
             ->where('profiles.status', 'active');
    })
    ->get();

排序和分页

ORDER BY

// 单字段排序
$users = db('users')
    ->orderBy('created_at', 'desc')
    ->get();

// 多字段排序 $users = db('users') ->orderBy('status', 'asc') ->orderBy('created_at', 'desc') ->get();

LIMIT 和 OFFSET

// LIMIT
$users = db('users')
    ->limit(10)
    ->get();

// OFFSET $users = db('users') ->offset(10) ->limit(10) ->get();

// 分页(LIMIT + OFFSET) $users = db('users') ->offset(20) ->limit(10) ->get();

随机排序

$users = db('users')
    ->orderByRaw('RAND()')
    ->limit(10)
    ->get();

聚合函数

COUNT

// 总记录数
$count = db('users')->count();

// 带条件 $count = db('users') ->where('status', 'active') ->count();

MAX / MIN

$maxAge = db('users')->max('age');
$minAge = db('users')->min('age');

AVG / SUM

$avgAge = db('users')->avg('age');
$totalScore = db('users')->sum('score');

GROUP BY

$stats = db('orders')
    ->select('user_id', db()->raw('COUNT(*) as order_count'), db()->raw('SUM(amount) as total'))
    ->groupBy('user_id')
    ->get();

HAVING

$users = db('orders')
    ->select('user_id', db()->raw('SUM(amount) as total'))
    ->groupBy('user_id')
    ->having('total', '>', 1000)
    ->get();

插入数据

单条插入

$id = db('users')->insert([
    'name' => 'John Doe',
    'email' => 'john@example.com',
    'created_at' => date('Y-m-d H:i:s'),
]);

批量插入

db('users')->insert([
    [
        'name' => 'John Doe',
        'email' => 'john@example.com',
    ],
    [
        'name' => 'Jane Doe',
        'email' => 'jane@example.com',
    ],
]);

插入并获取 ID

$id = db('users')->insertGetId([
    'name' => 'John Doe',
    'email' => 'john@example.com',
]);

更新数据

更新所有记录

db('users')->update(['status' => 'inactive']);

条件更新

db('users')
    ->where('status', 'pending')
    ->update(['status' => 'active']);

更新单个字段

db('users')
    ->where('id', 1)
    ->update(['email' => 'newemail@example.com']);

增量/减量

// 增量
db('users')
    ->where('id', 1)
    ->increment('score', 10);

// 减量 db('users') ->where('id', 1) ->decrement('score', 5);

// 带其他字段更新 db('users') ->where('id', 1) ->increment('score', 10, ['updated_at' => date('Y-m-d H:i:s')]);

删除数据

删除记录

// 条件删除
db('users')
    ->where('status', 'inactive')
    ->delete();

// 删除单条 db('users') ->where('id', 1) ->delete();

清空表

db('users')->truncate();

子查询

WHERE 子查询

$users = db('users')
    ->where('id', 'IN', function($query) {
        $query->select('user_id')
              ->from('orders')
              ->where('amount', '>', 1000);
    })
    ->get();

SELECT 子查询

$users = db('users')
    ->select([
        'users.*',
        db()->raw('(SELECT COUNT(*) FROM orders WHERE orders.user_id = users.id) as order_count')
    ])
    ->get();

原生 SQL

执行原生查询

$users = db()->query('SELECT * FROM users WHERE status = ?', ['active']);

// 获取标量值 $count = db()->queryScalar('SELECT COUNT(*) FROM users');

原生表达式

$users = db('users')
    ->select([
        'name',
        db()->raw('DATE_FORMAT(created_at, "%Y-%m") as month')
    ])
    ->get();

事务

基本事务

use function db_transaction;

db_transaction(function($conn) { db('users')->insert(['name' => 'John']); db('orders')->insert(['user_id' => 1, 'amount' => 100]); // 如果任何操作失败,会自动回滚 });

手动事务

$conn = db()->connection();
$conn->beginTransaction();

try { db('users')->insert(['name' => 'John']); db('orders')->insert(['user_id' => 1, 'amount' => 100]); $conn->commit(); } catch (\Exception $e) { $conn->rollBack(); throw $e; }

最佳实践

1. 使用参数绑定

// ✅ 正确:使用参数绑定
$users = db('users')
    ->where('email', $email)
    ->get();

// ❌ 错误:直接拼接 SQL(容易 SQL 注入) $users = db()->query("SELECT * FROM users WHERE email = '{$email}'");

2. 只查询需要的字段

// ✅ 正确:只查询需要的字段
$users = db('users')
    ->select(['id', 'name', 'email'])
    ->get();

// ❌ 错误:查询所有字段(浪费资源) $users = db('users')->get();

3. 使用索引字段

// ✅ 正确:使用索引字段查询
$user = db('users')->where('id', 1)->first();
$user = db('users')->where('email', 'user@example.com')->first();

// ❌ 错误:使用非索引字段(性能差) $user = db('users')->where('name', 'John')->first();

4. 避免 N+1 查询

// ❌ 错误:N+1 查询
$users = db('users')->get();
foreach ($users as $user) {
    $orders = db('orders')->where('user_id', $user->id)->get();
}

// ✅ 正确:使用 JOIN $users = db('users') ->leftJoin('orders', 'users.id', '=', 'orders.user_id') ->select('users.', 'orders.') ->get();

5. 使用分页

// ✅ 正确:使用分页
$users = db('users')
    ->offset(0)
    ->limit(20)
    ->get();

// ❌ 错误:一次性加载所有数据 $users = db('users')->get(); // 如果数据量大,会消耗大量内存

6. 使用事务保证数据一致性

// ✅ 正确:使用事务
db_transaction(function($conn) {
    db('users')->insert(['name' => 'John']);
    db('orders')->insert(['user_id' => 1, 'amount' => 100]);
});

常见问题

Q: 如何调试 SQL 查询?

A: 使用 toSql() 方法查看生成的 SQL:

$query = db('users')->where('status', 'active');
echo $query->toSql(); // SELECT * FROM users WHERE status = ?

Q: 如何获取查询的绑定参数?

A: 使用 getBindings() 方法:

$query = db('users')->where('status', 'active');
$bindings = $query->getBindings();

Q: 支持哪些数据库?

A: 支持 MySQL、PostgreSQL 和 SQLite。

Q: 如何处理 NULL 值?

A: 使用 whereNull()whereNotNull()

$users = db('users')->whereNull('deleted_at')->get();

相关文档