Eloquent ORM 自定義 builder——實現 find_in_set 查詢

Mr-houzi發表於2020-08-20

上篇文章其實已經介紹了自定義 builder,可是舉得了 page 例子不夠恰當,這次用自定義 builder 實現一下 MySQL 的 find_in_set() 查詢。

find_in_set()

熟悉 find_in_set 的同學直接跳至下一節。

find_in_set(str, list)

str 要搜尋的值
list 待搜尋列表,字元間以英文逗號分隔 eg: foo,bar,qux
返回 str 在 list 中的位置(從1開始),搜尋不到則返回0

例子:

select find_in_set('foo', 'foo,bar,qux'); // 返回1
select find_in_set('qux', 'foo,bar,qux'); // 返回3
select find_in_set('abc', 'foo,bar,qux'); // 返回0

當 find_in_set() 與 where 配合能達到“標籤”搜尋的目的。假如文章表如下:

id title tag
1 This is an article title foo,bar,qux
2 This is another article title abc,def,foo

使用 where + find_in_set 可以查詢帶 foo 標籤的文章。

select * from article where find_in_set('foo', `tag`);

自定義 builder 實現 find_in_set 查詢

模型層父類繼承 Eloquent Model ,在構造方法中利用 macro 註冊自定義的 builder。示例程式碼如下:

class Model extends \Illuminate\Database\Eloquent\Model
{
    public function __construct(array $attributes = [])
    {
        /**
         * 自定義 builder
         */

        /**
         * findInSet() 方法
         * 引數: $field 欄位 ;$value string 要查詢的值
         * 使用方法:query鏈式呼叫
         */
        \Illuminate\Database\Query\Builder::macro('findInSet', function ($field, $value) {
            return $this->whereRaw("FIND_IN_SET(?, {$field})", $value);
        });

        parent::__construct($attributes);
    }
}

如何使用

Article::query()->findInSet('tag', 'foo');

Finished!

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章