nmggy / laravel-hasin
Laravel 框架关系 has in 实现
v0.1.1
2021-07-10 02:57 UTC
Requires
- php: >=7.1
- laravel/framework: >=5.8
This package is not auto-updated.
Last update: 2024-09-29 15:38:40 UTC
README
英文 | 中文
# LARAVEL HASIN<a href="https://packagist.org.cn/packages/biiiiiigmonster/hasin"><img src="https://img.shields.io/packagist/dt/biiiiiigmonster/hasin.svg?color=" /></a>
<a><img src="https://img.shields.io/badge/php-7.1+-59a9f8.svg?style=flat" /></a>
hasin
是基于 where in
语法查询 Laravel ORM 关系的 composer 包,可以在某些业务场景中替代基于 where exists
语法实现的 has
,以获得更高的性能。
环境
- PHP >= 7.1
- laravel >= 5.8
安装
composer require nmggy/laravel-hasin
介绍
Laravel ORM 的关系非常强大,基于关系的查询 has
也为我们提供了许多灵活的调用方法。然而,在某些情况下,has
是通过 where exists 语法实现的。
例如
// User hasMany Post
User::has('posts')->get();
select * from users where exists (select * from posts where users.id = posts.user_id)
'exists' 是对外部表的循环,然后每次查询内部表(子查询)。因为用于内部表查询的索引(内部表效率高,因此可以用作大型表),以及外部表需要遍历的程度,是不可避免的(尽量使用小表),所以对于大型内部表使用 'exists' 可以提高效率。
然而,当 User 有大量数据时,将会出现性能问题,所以 where in 语法将大大提高性能。
select * from users where users.id in (select posts.user_id from posts)
'in' 是将外表和内表进行哈希连接,首先查询内表,然后匹配内表的结果与外表,并使用外表的索引(外表效率高,可以用于大型表)。大多数内表需要查询,这是不可避免的。因此,对于大型外表使用 'in' 可以提高效率。
因此,在代码中使用 has(hasMorph)
或 hasIn(hasMorphIn)
应根据 数据量 确定
<?php
/**
* SQL:
*
* select * from `users`
* where exists
* (
* select * from `posts`
* where `users`.`id` = `posts`.`user_id`
* )
* limit 10 offset 0
*/
$users = User::has('posts')->paginate(10);
/**
* SQL:
*
* select * from `users`
* where `users`.`id` in
* (
* select `posts`.`user_id` from `posts`
* )
* limit 10 offset 0
*/
$users = User::hasIn('posts')->paginate(10);
使用示例
hasIn(hasMorphIn)
支持 Laravel ORM 中所有的 关系
。调用方式和内部实现与框架的 has(hasMorph)
完全一致。
hasIn
// hasIn
User::hasIn('posts')->get();
// orHasIn
User::where('age', '>', 18)->orHasIn('posts')->get();
// doesntHaveIn
User::doesntHaveIn('posts')->get();
// orDoesntHaveIn
User::where('age', '>', 18)->orDoesntHaveIn('posts')->get();
whereHasIn
// whereHasIn
User::whereHasIn('posts', function ($query) {
$query->where('votes', '>', 10);
})->get();
// orWhereHasIn
User::where('age', '>', 18)->orWhereHasIn('posts', function ($query) {
$query->where('votes', '>', 10);
})->get();
// whereDoesntHaveIn
User::whereDoesntHaveIn('posts', function ($query) {
$query->where('votes', '>', 10);
})->get();
// orWhereDoesntHaveIn
User::where('age', '>', 18)->orWhereDoesntHaveIn('posts', function ($query) {
$query->where('votes', '>', 10);
})->get();
hasMorphIn
Image::hasMorphIn('imageable', [Post::class, Comment::class])->get();
嵌套关系
User::hasIn('posts.comments')->get();