Eloquent ORM 自定义 builder——实现 find_in_set 查询

上篇文章其实已经介绍了自定义 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 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 2

如何能定义个方法每个model 能重写这个方法的实现是不是好点?

3年前 评论
Mr-houzi (楼主) 3年前

学到了,这个函数真的太有用了。 :+1: :+1:

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!