nmggy / lumen-hasin
Laravel 框架关系 has in 实现
v1.0.0
2021-07-10 06:52 UTC
Requires
- php: >=7.1
- laravel/lumen-framework: ^5.8|^8.0
This package is not auto-updated.
Last update: 2024-09-29 19:49:20 UTC
README
英文 | 中文
# LUMEN 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
- lumen >= 5.8 或 >= 8.0
安装
composer require y-lincoln/lumen-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();