Yii2 的复杂条件SQL语句一共有哪些?使用场景是什么?底层原理是什么?

1. Yii2 的复杂条件 SQL 语句一共有哪些?

(1) 常见的复杂条件
  • ANDOR 条件

    • 使用 andWhere()orWhere() 方法动态组合条件。
  • 嵌套条件

    • 使用数组或闭包构建嵌套的 ANDOR 条件。
  • INNOT IN 条件

    • 使用 in()notIn() 方法处理范围查询。
  • LIKEILIKE 条件

    • 使用 like()ilike() 方法处理模糊查询。
  • 比较条件

    • 使用 ><>=<= 等操作符进行比较。
  • BETWEEN 条件

    • 使用 between() 方法处理区间查询。
  • EXISTS 子查询

    • 使用子查询判断记录是否存在。
  • 联表查询

    • 使用 join()innerJoin()leftJoin() 等方法执行联表操作。

2. 使用场景

(1) 动态查询
  • 示例:
    $query = (new Query())
        ->from('user')
        ->where(['status' => 1])
        ->andWhere(['age' => 30]);
    
  • 场景:
    • 根据用户输入或其他动态条件构建查询。
(2) 复杂业务逻辑
  • 示例:
    $query = (new Query())
        ->from('user')
        ->where(['or', ['status' => 1], ['age' => 30]]);
    
  • 场景:
    • 需要处理复杂的条件组合(如 ANDOR 混合)。
(3) 范围查询
  • 示例:
    $query = (new Query())
        ->from('user')
        ->where(['in', 'id', [1, 2, 3]]);
    
  • 场景:
    • 查询满足特定范围的数据。
(4) 模糊查询
  • 示例:
    $query = (new Query())
        ->from('user')
        ->where(['like', 'name', 'John']);
    
  • 场景:
    • 搜索包含特定关键字的记录。
(5) 区间查询
  • 示例:
    $query = (new Query())
        ->from('user')
        ->where(['between', 'age', 20, 30]);
    
  • 场景:
    • 查询满足某个区间的记录。
(6) 子查询
  • 示例:
    $subQuery = (new Query())->select('id')->from('post');
    $query = (new Query())
        ->from('user')
        ->where(['exists', $subQuery]);
    
  • 场景:
    • 判断记录是否存在于另一个表中。
(7) 联表查询
  • 示例:
    $query = (new Query())
        ->from('user')
        ->innerJoin('profile', 'user.id = profile.user_id');
    
  • 场景:
    • 查询多个表之间的关联数据。

3. 底层原理

(1) 数据存储
  • 数据库表
    • 查询的目标数据通常存储在数据库中。
(2) 程序流

当构建复杂条件的 SQL 语句时,系统会执行以下步骤:

  1. 解析条件

    • 将传入的条件解析为 SQL 表达式。
  2. 合并条件

    • 将新条件与现有条件合并(通过 ANDOR 连接)。
  3. 生成 SQL

    • 将所有条件转换为最终的 SQL 查询语句。
  4. 执行查询

    • 调用底层的数据库驱动执行查询。
  5. 返回结果

    • 返回查询结果。
(3) 数据流
  • 写入数据

    • 查询条件被动态构建并传递给数据库。
  • 读取数据

    • 数据库返回查询结果,供调用者使用。

4. 示例代码及详细注释

以下是一个完整的示例,展示如何使用 Yii2 构建复杂条件的 SQL 查询,并附上详细注释。

<?php

namespace app\controllers;

use yii\web\Controller;
use yii\db\Query;

class UserController extends Controller
{
    public function actionIndex()
    {
        // 创建 Query 对象
        // 作用:初始化一个查询对象,用于构建 SQL 查询。
        // 原因:Query 类提供了一种链式调用的方式,便于动态构建查询。
        // 知识点:Yii2 的 Query 类,用于构建数据库查询。
        $query = new Query();

        // 指定查询的表
        // 作用:定义查询的目标表(如 user 表)。
        // 原因:明确查询的数据来源。
        // 知识点:Query 类的 from() 方法,用于指定查询表。
        $query->from('user');

        // 添加初始条件
        // 作用:筛选状态为 1 的用户。
        // 原因:确保查询结果符合业务需求。
        // 知识点:Query 类的 where() 方法,用于添加查询条件。
        $query->where(['status' => 1]);

        // 动态添加 AND 条件
        // 作用:进一步筛选年龄为 30 的用户。
        // 原因:支持动态构建复杂的查询条件。
        // 知识点:Query 类的 andWhere() 方法,用于动态添加 AND 条件。
        $query->andWhere(['age' => 30]);

        // 动态添加 OR 条件
        // 作用:筛选状态为 2 的用户(或条件)。
        // 原因:支持复杂的条件组合。
        // 知识点:Query 类的 orWhere() 方法,用于动态添加 OR 条件。
        $query->orWhere(['status' => 2]);

        // 添加范围查询
        // 作用:筛选 ID 在 [1, 2, 3] 范围内的用户。
        // 原因:支持范围查询。
        // 知识点:Query 类的 in() 方法,用于处理范围查询。
        $query->andWhere(['in', 'id', [1, 2, 3]]);

        // 添加模糊查询
        // 作用:筛选名字包含 "John" 的用户。
        // 原因:支持模糊匹配。
        // 知识点:Query 类的 like() 方法,用于处理模糊查询。
        $query->andWhere(['like', 'name', 'John']);

        // 添加区间查询
        // 作用:筛选年龄在 20 到 30 之间的用户。
        // 原因:支持区间查询。
        // 知识点:Query 类的 between() 方法,用于处理区间查询。
        $query->andWhere(['between', 'age', 20, 30]);

        // 添加子查询
        // 作用:筛选存在对应记录的用户。
        // 原因:支持子查询。
        // 知识点:Query 类的 exists() 方法,用于处理子查询。
        $subQuery = (new Query())->select('id')->from('post');
        $query->andWhere(['exists', $subQuery]);

        // 执行查询并获取结果
        // 作用:从数据库中加载符合条件的记录。
        // 原因:将查询结果返回给调用者。
        // 知识点:Query 类的 all() 方法,用于返回所有记录。
        $users = $query->all();

        // 渲染视图并传递数据
        // 作用:将查询结果传递给视图文件,用于展示。
        // 原因:视图负责展示数据,控制器负责准备数据。
        // 知识点:Yii2 的 render() 方法,用于渲染视图文件。
        return $this->render('index', [
            'users' => $users,
        ]);
    }
}

5. 注意事项

(1) 条件顺序
  • 确保 andWhere()orWhere() 的调用顺序正确,避免逻辑错误。
(2) 参数绑定
  • 如果条件中包含用户输入,建议使用参数绑定防止 SQL 注入。
(3) 性能优化
  • 如果查询涉及大量数据,建议对查询进行分页或缓存。

6. 程序流和数据流

(1) 程序流
  1. 创建查询对象

    • 初始化 Query 对象。
  2. 添加初始条件

    • 使用 where() 方法添加初始条件。
  3. 动态添加条件

    • 使用 andWhere()orWhere()in()like() 等方法动态添加复杂条件。
  4. 生成 SQL

    • 将所有条件转换为最终的 SQL 查询语句。
  5. 执行查询

    • 调用底层的数据库驱动执行查询。
  6. 返回结果

    • 返回查询结果。
(2) 数据流
  • 写入数据

    • 查询条件被动态构建并传递给数据库。
  • 读取数据

    • 数据库返回查询结果,供调用者使用。

7. 总结

  • 组成部分

    • ANDOR 条件。
    • 嵌套条件。
    • INNOT IN 条件。
    • LIKEILIKE 条件。
    • 比较条件。
    • BETWEEN 条件。
    • EXISTS 子查询。
    • 联表查询。
  • 使用场景

    • 动态查询。
    • 复杂业务逻辑。
    • 范围查询。
    • 模糊查询。
    • 区间查询。
    • 子查询。
    • 联表查询。
  • 底层原理

    • 数据存储在数据库中。
    • 使用链式调用动态构建查询条件。
  • 程序流和数据流

    • 写入数据:查询条件被动态构建并传递给数据库。
    • 读取数据:数据库返回查询结果,供调用者使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值