nmggy/laravel-hasin

Laravel 框架关系 has in 实现

v0.1.1 2021-07-10 02:57 UTC

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();

许可证

MIT