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

328 天前
 via
<?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);

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

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

这句话是什么意思呢。还有这个 query builder 有什么可秀的吗?
via
328 天前
@sunznx 当 params 数组中有这些字段时,按照这些字段自动生成 where 、whereIn, whereLike, whereBetween 等,意思就是我这个 querybuilder 支持这些查询字段,并规定字段是哪种查询,默认是 where 或者 whereIN (当参数为数组时)
zhouxiao
328 天前
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
328 天前
这种逻辑,写原生的 sql 更难看懂。其他语言估计能写出 200 行
weaving
328 天前
一个弱类型语言,老要求什么类型安全,要什么自行车。
xuyang2
328 天前
happy32199
328 天前
@via 这么阴阳 有成就感?
loginv2
327 天前
有一说一 这种程度的逻辑 真写 SQL , 我俩星期就看不懂了, 楼主代码虽然看着丑,但是是真有用
JaguarJack
324 天前
@loginv2 不用两周,两天后你就看不懂了。经历过
47d7tEUBp521E8fJ
311 天前
你这个->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();

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1004442

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX