我对laravel很新,到目前为止,我真的很喜欢雄辩和查询,但是一旦查询变得更加复杂,我的脑袋开始受伤...我已经完成了2个工作实例很长一段时间后,也许你伙计们可以帮助我优化它。我先给出例子,然后给出(dis)优点
首先是DB :: select ...老实说,我认为比第二个例子更具可读性......或许我只是在做错误的xD构建器。
$shared_slugs = Magic::in_query($this->shared_slugs);
$items = DB::select("
SELECT * FROM f_admin_items
WHERE
active = 1
AND (
slug IN $shared_slugs
OR
:treshhold <= :urank AND id IN (SELECT admin_item_id FROM f_user_access WHERE user_id = :uid)
OR
:treshhold > :urank AND `rank` >= :urank
)
ORDER BY `order` ASC
", [
'treshhold' => $this->threshold_rank,
'urank' => $user_rank,
'uid' => $user_id
]);
使用命名参数绑定总体上非常有效。基本上,菜单项必须始终处于活动状态,加上(1 OR 2 OR 3)。例如,仪表板被接受为共享slu ..否则有一些排名检查。
现在我一直在努力用滔滔不绝的en查询构建器来做这个= /我不认为设置关系是没有必要的,因为我只将它用于菜单和中间件。在这种情况下,仅包含admin_item_id和user_id的f_user_access表并不真正用作数据透视表,并且不会在其他任何地方使用。
$items =
$this->where( 'active', 1 )
->where( function ($query) {
$query->whereIn( 'slug', $this->shared_slugs )
->orWhere(function ($query) {
$query->whereRaw( $this->threshold_rank.' <= '.$this->user_rank )
->whereIn('id', function ($query) {
$query->select('admin_item_id')->from('f_user_access')->where('user_id', $this->user_id)->get();
});
})
->orWhere(function ($query) {
$query->whereRaw( $this->threshold_rank.' > '.$this->user_rank )
->where( 'rank', '>=', $this->user_rank );
});
})->orderBy( 'order', 'ASC' )->get();
我喜欢第二个是我可以将$ shared_slugs作为数组传递的事实,我不必先将其转换为字符串。但除此之外,我真的很讨厌它的外观,在哪里(函数($ query){})等...最重要的是传递给这个函数的$ id,在where.functions中是不可访问的,所以我必须先在课堂上定义它们。
我喜欢的第一个因为命名绑定而且它不会读得那么糟糕:S,vars也可以访问..在下方,我必须调用此函数将共享slugs转换为数组。
不使用eloquent和querybuilder真的那么糟糕吗?至少在某些情况下......你会做些什么来使第二个例子更好? = /
UPDATE ::
由于答案和反馈,我抛弃了原始的sql。当前函数中有5个作用域,并且为user_access创建了一个(小)模型。
$items =
$this->active() //Only active items AND... 1, 2 or 3
->where( function ($query) {
$query->shared_slug() // 1
->orWhere(function ($query) { // OR 2
$query->access_required()
->whereIn('id', UserAccess::get_access( $this->user_id ) );
})
->orWhere(function ($query) { // OR 3
$query->no_access_required()
->whereRaw( 'rank >= '.$this->user_rank );
});
})->ASC()->get();
答案 0 :(得分:3)
使用查询构建器的主要好处是它将您从您选择的存储所使用的语言(即MySQL,Oracle,SQLite等)中抽象出来。如果您曾经切换过数据库类型,那么您可能会遇到很多问题。重构原始SQL。相信我,当你开始一个项目并且了解情况时,这并不漂亮。
然而,总有一些警告,这正是Eloquent能够使用原始语句的原因。