Skip to content

Latest commit

 

History

History
140 lines (105 loc) · 4.98 KB

README-CN.md

File metadata and controls

140 lines (105 loc) · 4.98 KB

English | 中文

LARAVEL HASIN

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Coverage Status Scrutinizer Code Quality Total Downloads

hasin是一个基于where in语法实现的Laravel ORM关联关系查询的扩展包,部分业务场景下可以替代Laravel ORM中基于where exists语法实现的has,以获取更高的性能。

安装

Laravel 版本 安装命令
Laravel 11 composer require biiiiiigmonster/hasin:^4.0
Laravel 10 composer require biiiiiigmonster/hasin:^3.0
Laravel 9 composer require biiiiiigmonster/hasin:^2.0
Laravel 5.5 ~ 8 composer require biiiiiigmonster/hasin:^1.0

简介

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是对外表做loop循环,每次loop循环再对内表(子查询)进行查询,那么因为对内表的查询使用的索引(内表效率高,故可用大表),而外表有多大都需要遍历,不可避免(尽量用小表),故内表大的使用exists,可加快效率。

但是当User表数据量较大的时候,就会出现性能问题,那么这时候用where in语法将会极大的提高性能

select * from users where users.id in (select posts.user_id from posts)

in是把外表和内表做hash连接,先查询内表,再把内表结果与外表匹配,对外表使用索引(外表效率高,可用大表),而内表多大都需要查询,不可避免,故外表大的使用in,可加快效率。

因此在代码中使用has(hasMorph)或者hasIn(hasMorphIn)应由数据体量来决定……

/**
 * 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);

Laravel ORM十种关联关系多达248种实际业务case sql输出可查看有道云笔记

使用

此扩展方法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();

测试

composer test

联系交流

wx:biiiiiigmonster(备注:hasin)

协议

MIT 协议