V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
via
V2EX  ›  PHP

必须秀出我的 PHP 史上无敌的 QueryBuilder!

  •  
  •   via · 334 天前 · 3071 次点击
    这是一个创建于 334 天前的主题,其中的信息可能已经有所发展或是发生改变。
    <?php
    // ...
    Arr::renameKey($params, ['user_source_title' =>  'user_source.title']);
    
    $builder = new QueryBuilder(User::class);
    $builder->joinTo(UserSource::class);
    $builder->joinFrom(UserTanPoint::class);
    $builder->setCondition([
        'id', 'cellphone', 'status', 'user_source_id', 'user_source.title' => 'fuzzy',
        'province_name', 'city_name', 'area_name', 'created_at' => 'range'
    ]);
    
    if (!empty($params['tag_id'])) {
        $builder->exposeBuilder()
            ->whereIn('user.id', function ($q) use ($params) {
                $q->select('user_id')
                    ->from(with(new UserTag)->getTable())
                    ->where('tag_id', $params['tag_id'])
                    ->distinct();
        });
    }
    
    // $builder->select('user.*');
    $builder->addSelect('user_source.name AS user_source_name');
    $builder->addSelect('user_tan_point.point');
    
    return $builder->query($params);
    

    各位看官就看代码猜功能吧🙃,还有一些特殊的用法和额外参数这个例子没展示出来

    19 条回复    2024-01-15 09:06:54 +08:00
    happy32199
        1
    happy32199  
       334 天前 via iPhone
    还不如直接写 sql 呢
    hefish
        2
    hefish  
       334 天前
    这个。。。一般这样的 orm ,我一定会在旁边备注一下 具体干的活和原生的 SQL ,不然时间长了肯定忘了是干啥用的。
    via
        3
    via  
    OP
       334 天前
    @happy32199 啊对对对对
    cleanery
        4
    cleanery  
       334 天前
    这... SPL(Structured Process Language)思想吧
    nikenidage1
        5
    nikenidage1  
       334 天前
    这。。。真的太丑了。。还不是强类型,都是字符串。。。
    BeijingBaby
        6
    BeijingBaby  
       334 天前 via iPhone
    代码量好大😓
    flyqie
        7
    flyqie  
       334 天前 via Android
    好奇这个跟 thinkorm 比起来怎么样
    yooomu
        8
    yooomu  
       334 天前
    不怎么懂 PHP ,但这封装了一大堆,用起来还全是字符串没有类型安全,感觉不如直接写 SQL ,起码还能用上 ide 的语法检查和智能提示
    Masoud2023
        9
    Masoud2023  
       334 天前
    sunznx
        10
    sunznx  
       334 天前
    ```
    $builder->setCondition([
    'id', 'cellphone', 'status', 'user_source_id', 'user_source.title' => 'fuzzy',
    'province_name', 'city_name', 'area_name', 'created_at' => 'range'
    ]);
    ```

    这句话是什么意思呢。还有这个 query builder 有什么可秀的吗?
    via
        11
    via  
    OP
       334 天前
    @sunznx 当 params 数组中有这些字段时,按照这些字段自动生成 where 、whereIn, whereLike, whereBetween 等,意思就是我这个 querybuilder 支持这些查询字段,并规定字段是哪种查询,默认是 where 或者 whereIN (当参数为数组时)
    zhouxiao
        12
    zhouxiao  
       334 天前
    GPT:

    从提供的 PHP 代码中,我们可以看出它是在使用一个自定义的 QueryBuilder 类来动态构建一个 SQL 查询。这个查询涉及到三个表:User, UserSource, 和 UserTanPoint 。它还涉及到一个可能的条件筛选和一个子查询用于处理标签 ID 。请注意,由于没有完整的上下文和数据库的具体结构,以下的 SQL 语句是基于假设和代码片段中的信息推断出来的。

    原生的 SQL 查询可能看起来像这样:

    ```sql
    SELECT
    u.*,
    us.name AS user_source_name,
    utp.point
    FROM
    users u
    INNER JOIN user_sources us ON u.user_source_id = us.id
    INNER JOIN user_tan_points utp ON u.id = utp.user_id
    WHERE
    u.id = :id AND
    u.cellphone = :cellphone AND
    u.status = :status AND
    us.title LIKE '%fuzzy%' AND
    u.province_name = :province_name AND
    u.city_name = :city_name AND
    u.area_name = :area_name AND
    u.created_at BETWEEN :created_at_start AND :created_at_end
    ```

    如果 tag_id 参数不为空,则会添加一个 IN 子句:

    ```sql
    AND u.id IN (
    SELECT DISTINCT user_id
    FROM user_tags
    WHERE tag_id = :tag_id
    )
    ```

    在上述 SQL 中,:id, :cellphone, :status, :province_name, :city_name, :area_name, :created_at_start, :created_at_end, 和 :tag_id 是参数占位符,您应该在实际的查询执行中用实际的值来替换它们。如果 user_source.title 字段使用了 LIKE '%fuzzy%',则表明它是模糊匹配,%fuzzy% 应替换为用户提供的实际搜索词。

    由于 created_at 使用了 'range',这通常意味着搜索一个时间区间,这里使用了 BETWEEN 来表示。

    请记住,由于缺少完整的信息,这个查询可能需要根据您的实际数据库架构和业务逻辑进行调整。特别是 JOIN 条件和 WHERE 子句可能需要更多的上下文来准确构建。
    kphcdr
        13
    kphcdr  
       334 天前
    这种逻辑,写原生的 sql 更难看懂。其他语言估计能写出 200 行
    weaving
        14
    weaving  
       334 天前
    一个弱类型语言,老要求什么类型安全,要什么自行车。
    happy32199
        16
    happy32199  
       334 天前 via iPhone
    @via 这么阴阳 有成就感?
    loginv2
        17
    loginv2  
       334 天前
    有一说一 这种程度的逻辑 真写 SQL , 我俩星期就看不懂了, 楼主代码虽然看着丑,但是是真有用
    JaguarJack
        18
    JaguarJack  
       331 天前
    @loginv2 不用两周,两天后你就看不懂了。经历过
    47d7tEUBp521E8fJ
        19
    47d7tEUBp521E8fJ  
       318 天前
    你这个->setCondition ,全是字符串指定什么类型的查询,用久了肯定容易忘掉里面要设置什么参数。我都是直接在 thinkphp 的 ORM 上面套一层,直接这么指定,还有 IDE 提示,
    $this->_query(Business::class)
    ->like('name')
    ->equal('business_no')
    ->dateBetween('create_at')
    ->timeBetween('update_at')
    ->in('id')
    ->valueRange(['start_time', 'end_time'])
    ->select();
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4674 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 05:36 · PVG 13:36 · LAX 21:36 · JFK 00:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.