Laravel查询中orWhere逻辑的正确使用与优化

laravel查询中orwhere逻辑的正确使用与优化

针对Laravel查询中orWhere条件链导致返回所有数据的问题,本教程将深入解析其背后的SQL逻辑,并提供两种专业的解决方案:使用闭包(回调函数)正确分组orWhere条件,以及通过局部作用域(Local Scope)封装查询逻辑,以提高代码的可读性和可维护性,同时强调处理空搜索词的重要性。

问题解析:Laravel orWhere的陷阱

在Laravel中构建数据库查询时,where和orWhere方法用于添加条件。当需要在一个查询中组合多个OR条件时,如果不进行适当的分组,可能会导致意外的结果。常见的问题是,当搜索词为空字符串时,LIKE ‘%%’条件会匹配数据库中的所有记录,从而返回所有数据而非特定结果。

考虑以下原始搜索功能代码:

搜索表单 (zuojiankuohaophpcnform>)

    

注意: 原始表单中input缺少name=”search”属性,这会导致$request->input(‘search’)无法获取到值。这里已修正。

控制器 (UploadController.php)

public function search(Request $request){    $searching = $request->input('search'); // 获取搜索词    // 原始查询:可能返回所有数据    $search = MusicUpload::query()            ->where('filename','LIKE',"%{$searching}%")            ->orWhere('artistname','LIKE',"%{$searching}%")            ->orWhere('albumname','LIKE',"%{$searching}%")            ->get();    return view('pages.search',compact('search'));}

当$searching变量为空字符串(例如用户直接点击搜索按钮而未输入任何内容)时,”%{$searching}%”会变成”%%”。此时,SQL查询大致会是这样:SELECT * FROM music_uploads WHERE filename LIKE ‘%%’ OR artistname LIKE ‘%%’ OR albumname LIKE ‘%%’LIKE ‘%%’是一个几乎总是为真的条件(除非字段为NULL),因此这个查询会返回music_uploads表中的所有数据。此外,即使$searching不为空,这种链式orWhere在更复杂的查询中也可能与前面的AND条件产生不符合预期的逻辑。

解决方案一:使用闭包(Callback)分组orWhere条件

为了确保OR条件作为一个整体进行评估,我们应该使用闭包(回调函数)来分组这些条件。这在SQL中相当于使用了括号,明确了条件的优先级。

修改后的控制器 (UploadController.php)

use IlluminateHttpRequest;use AppModelsMusicUpload; // 确保引入了模型class UploadController extends Controller{    public function search(Request $request)    {        $searching = $request->input('search');        // 检查搜索词是否为空,如果为空则不执行查询或返回空结果        if (empty($searching)) {            $search = collect(); // 返回一个空的集合            return view('pages.search', compact('search'));        }        // 使用闭包分组 OR 条件        $search = MusicUpload::query()            ->where(function ($query) use ($searching) {                $query->where('filename', 'LIKE', "%{$searching}%")                      ->orWhere('artistname', 'LIKE', "%{$searching}%")                      ->orWhere('albumname', 'LIKE', "%{$searching}%");            })            ->get(); // 执行查询并获取结果        return view('pages.search', compact('search'));    }}

解析:

->where(function ($query) use ($searching) { … }):这个闭包接收一个查询构建器实例$query,并允许你在其中定义一组嵌套的条件。use ($searching)确保闭包内部可以访问到外部的$searching变量。闭包内部的所有where和orWhere条件会被包裹在SQL的括号中,例如:WHERE (filename LIKE ‘%term%’ OR artistname LIKE ‘%term%’ OR albumname LIKE ‘%term%’)。这确保了逻辑的正确性。重要提示:处理空搜索词。在执行查询之前,我们增加了if (empty($searching))的检查。如果搜索词为空,我们直接返回一个空的集合collect(),这样可以避免LIKE ‘%%’带来的问题,并向用户展示“未找到结果”的信息。

解决方案二:利用局部作用域(Local Scope)封装查询逻辑

对于更复杂的查询或需要在多个地方复用相同查询逻辑的情况,使用局部作用域(Local Scope)是更好的选择。它将查询逻辑封装在模型内部,提高了代码的内聚性和可读性。

修改模型 (MusicUpload.php)

where(function ($q) use ($search) {                $q->where('filename', 'LIKE', "%{$search}%")                  ->orWhere('artistname', 'LIKE', "%{$search}%")                  ->orWhere('albumname', 'LIKE', "%{$search}%");            });        }        return $query; // 如果搜索词为空,则返回原始查询构建器,不添加任何搜索条件    }}

修改控制器 (UploadController.php)

use IlluminateHttpRequest;use AppModelsMusicUpload;class UploadController extends Controller{    public function search(Request $request)    {        $searching = $request->input('search');        // 调用模型中定义的局部作用域        // scopeSearch方法会自动处理空搜索词的情况        $search = MusicUpload::search($searching)->get();        return view('pages.search', compact('search'));    }}

解析:

scopeSearch($query, $search):这是一个局部作用域的定义。scope前缀是约定,实际调用时只需使用search()。它接收当前查询构建器实例$query和搜索词$search作为参数。在scopeSearch内部,我们同样使用了闭包来分组OR条件,并且增加了if (! empty($search))的判断。如果$search为空,则不添加任何搜索条件,直接返回原始$query。这意味着在控制器中,即使$searching为空,MusicUpload::search($searching)->get()也不会因LIKE ‘%%’而返回所有数据,而是根据业务逻辑决定是返回空集还是所有数据(如果get()在空搜索词时没有其他where条件)。控制器代码变得更加简洁和易读,业务逻辑被封装在模型中,符合“胖模型,瘦控制器”的设计原则。

视图文件 (search.blade.php)

无论采用哪种解决方案,视图文件保持不变,它负责渲染搜索结果。

@extends('layouts.app') {{-- 假设你有一个基础布局文件 --}}@section('content')    @if($search->isNotEmpty())        
@foreach ($search as $searched)
{{ $searched->filename }}

专辑: {{ $searched->albumname }}

艺术家: {{ $searched->artistname }}
@endforeach
@else @endif@endsection

注意: 为了更好的用户体验,对视图内容进行了美化和结构优化,使用了list-group和alert等Bootstrap类。

总结与最佳实践

正确处理Laravel中的orWhere条件对于构建健壮的搜索功能至关重要。

使用闭包分组OR条件: 这是解决orWhere逻辑混淆最直接有效的方法,它模拟了SQL中的括号,确保了条件的正确评估。利用局部作用域封装: 对于可复用的搜索逻辑,将其封装在模型局部作用域中是最佳实践。这不仅提高了代码的可读性和维护性,还使得控制器更加专注于请求处理和视图渲染。始终处理空搜索词: 在应用搜索条件之前,务必检查搜索词是否为空。如果为空,通常应该返回空结果集,而不是所有数据。这可以避免不必要的数据库负载,并提供更好的用户体验。考虑索引: 对于频繁搜索的字段,确保数据库中建立了适当的索引(例如,filename, artistname, albumname),这将显著提高查询性能。全文搜索: 对于大量文本数据和更复杂的搜索需求,可以考虑使用数据库的全文搜索功能(如MySQL的FULLTEXT索引)或集成专门的搜索服务(如Elasticsearch)。

通过遵循这些原则,你可以构建出高效、准确且易于维护的Laravel搜索功能。

以上就是Laravel查询中orWhere逻辑的正确使用与优化的详细内容,更多请关注php中文网其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/32085.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
Spring Retry中的指数退避策略配置
上一篇 2025年11月4日 03:15:01
比亚迪、长城疑似互掐,从“油箱门”到“鬼灯”隐喻
下一篇 2025年11月4日 03:15:05

相关推荐

  • sublime怎么配置React开发环境_sublime搭建React开发环境步骤

    sublime怎么配置React开发环境_sublime搭建React开发环境步骤sublime怎么配置React开发环境_sublime搭建React开发环境步骤sublime怎么配置React开发环境_sublime搭建React开发环境步骤sublime怎么配置React开发环境_sublime搭建React开发环境步骤

    首先安装Package Control,再通过它安装Babel、Emmet、SublimeLinter等插件;接着将.js/.jsx文件语法设为JavaScript (Babel)以支持JSX高亮;然后配置ESLint实现代码检查;最后可选配置构建系统运行npm start命令。 要在 Sublim…

    2026年9月24日 用户投稿
    000
  • 神马搜索App夜间模式使用详解_神马搜索App护眼设置优化

    神马搜索App夜间模式使用详解_神马搜索App护眼设置优化神马搜索App夜间模式使用详解_神马搜索App护眼设置优化神马搜索App夜间模式使用详解_神马搜索App护眼设置优化神马搜索App夜间模式使用详解_神马搜索App护眼设置优化

    开启夜间模式可降低神马搜索App的屏幕亮度与蓝光,缓解暗光环境下的视觉疲劳。首先进入“我的”-“设置”-“显示与字体”,开启夜间模式;随后可设置定时切换,如晚9点至早7点自动启用;接着调节夜间亮度与对比度,匹配环境光线;最后根据偏好自定义夜间主题颜色,如深蓝或墨绿,提升观感舒适度。 如果您在夜间或光…

    2026年9月24日 用户投稿
    100
  • php-gd怎么销毁图像资源_php-gd释放内存中的图像

    使用imagedestroy()函数销毁PHP-GD图像资源以避免内存泄漏。创建的资源如$image需在处理后调用imagedestroy($image)释放,尤其在循环中应每轮结束前销毁资源,推荐结合is_resource()判断有效性,遵循“谁创建,谁销毁”原则,确保内存高效管理。 在使用 PH…

    2026年9月24日
    000
  • 夸克下载的电子书在哪个文件夹_夸克小说与电子书缓存位置

    夸克下载的电子书在哪个文件夹_夸克小说与电子书缓存位置夸克下载的电子书在哪个文件夹_夸克小说与电子书缓存位置夸克下载的电子书在哪个文件夹_夸克小说与电子书缓存位置夸克下载的电子书在哪个文件夹_夸克小说与电子书缓存位置

    夸克浏览器下载的电子书通常存于设备Download文件夹中,可经文件管理进入内部存储查找“Quark”子目录;在线阅读缓存则位于/Android/data/com.quark.browser/files下的Cache或Book目录,多为加密.dat文件;导出已下载电子书需通过App内书架的导出或分享…

    2026年9月24日 用户投稿
    500
  • MAC的Siri无法使用怎么办_macOS Siri功能故障排查与修复

    MAC的Siri无法使用怎么办_macOS Siri功能故障排查与修复MAC的Siri无法使用怎么办_macOS Siri功能故障排查与修复MAC的Siri无法使用怎么办_macOS Siri功能故障排查与修复MAC的Siri无法使用怎么办_macOS Siri功能故障排查与修复

    首先检查网络连接是否稳定,确认Siri服务状态正常,接着在系统设置中启用Siri并授予麦克风权限,通过终端重启Siri进程,必要时重置NVRAM/PRAM,最后创建新用户账户排除配置损坏问题。 如果您在使用Mac时发现Siri无法响应或功能异常,可能是由于网络连接、系统设置或权限问题导致。以下是排查…

    2026年9月24日 用户投稿
    000
  • 京东plus月卡能领双11券吗?京东plus有月卡吗

    京东plus月卡能领双11券吗?京东plus有月卡吗京东plus月卡能领双11券吗?京东plus有月卡吗京东plus月卡能领双11券吗?京东plus有月卡吗京东plus月卡能领双11券吗?京东plus有月卡吗

    京东PLUS月卡用户可领双11大额券,需在优惠期内保持会员有效,通过“我的-PLUS会员”进入领券中心,按时领取满减券并结合红包口令提升优惠。 如果您想在短时间内享受京东PLUS会员的专属优惠,但又不想长期付费,可能会考虑月卡服务。关于京东PLUS月卡是否能领取双11大额优惠券的问题,以下是相关信息…

    2026年9月24日 用户投稿
    000
  • mysql储存过程中循环语句有哪些

    mysql储存过程中循环语句有哪些mysql储存过程中循环语句有哪些mysql储存过程中循环语句有哪些mysql储存过程中循环语句有哪些

    MySQL存储过程中提供WHILE和REPEAT两种循环语句:WHILE循环:根据条件重复执行代码块,条件为真时继续执行。REPEAT循环:先执行代码块,再检查条件是否为真,为假则再次执行代码块。 MySQL存储过程中的循环语句 MySQL存储过程中支持以下两种循环语句: WHILE 循环 WHIL…

    2026年9月24日 用户投稿
    000
  • mysql存储过程保存在哪

    mysql存储过程保存在哪mysql存储过程保存在哪mysql存储过程保存在哪mysql存储过程保存在哪

    MySQL 存储过程保存在 mysql.proc 表中,该表存储了存储过程的所有信息,包括名称、定义、创建者和修改时间。 MySQL 存储过程保存在哪里? MySQL 中的存储过程保存在数据库的 mysql.proc 表中。这个表存储了所有在数据库中创建的存储过程的信息。 表结构 mysql.pro…

    2026年9月24日 用户投稿
    1700
  • 如何在Debian 10(Buster)Linux上安装MySQL

    了解如何在debian 10(buster)linux上安装mysql。本指南将引导您完成在最新版本的debian系统上安装mysql 8或mysql 5.7的步骤。 第1步 – 准备工作 首先,确保您拥有Debian 10系统的shell访问权限。如果是远程系统,可以通过SSH连接。W…

    2026年9月24日
    1000
  • sublime怎么去除购买弹窗_sublime关闭试用版购买提示的方法

    sublime怎么去除购买弹窗_sublime关闭试用版购买提示的方法sublime怎么去除购买弹窗_sublime关闭试用版购买提示的方法sublime怎么去除购买弹窗_sublime关闭试用版购买提示的方法sublime怎么去除购买弹窗_sublime关闭试用版购买提示的方法

    答案:可通过修改hosts文件、清理授权信息或降级版本缓解Sublime Text启动弹窗。具体操作包括屏蔽验证域名license.sublimehq.com、重命名Local目录下的Registry.dat文件,或安装旧版本并关闭更新提示,但建议支持正版以获得更好体验。 Sublime Text …

    2026年9月24日 用户投稿
    000
  • mysql存储过程在哪里写

    mysql存储过程在哪里写mysql存储过程在哪里写mysql存储过程在哪里写mysql存储过程在哪里写

    MySQL 存储过程存储在 MySQL 数据库中的 mysql.proc 表中。创建存储过程需要使用 CREATE PROCEDURE 语句,调用存储过程需要使用 CALL 语句。 MySQL 存储过程存储位置 存储过程在哪里写? MySQL 存储过程存储在 MySQL 数据库中。 详细说明: 存储…

    2026年9月24日 用户投稿
    500
  • 铁路12306电子发票下载失败怎么解决_铁路12306电子发票下载问题解决方案

    铁路12306电子发票下载失败怎么解决_铁路12306电子发票下载问题解决方案铁路12306电子发票下载失败怎么解决_铁路12306电子发票下载问题解决方案铁路12306电子发票下载失败怎么解决_铁路12306电子发票下载问题解决方案铁路12306电子发票下载失败怎么解决_铁路12306电子发票下载问题解决方案

    首先检查网络连接并重新尝试下载电子发票,若失败可联系12306客服重发,同时查看邮箱垃圾文件夹,最后可通过个人所得税App等工具同步管理发票。 如果您在尝试下载铁路12306电子发票时遇到失败情况,可能是由于网络连接、系统状态或权限设置等问题导致。以下是针对该问题的多种解决方案。 本文运行环境:iP…

    2026年9月24日 用户投稿
    100
  • 比漫熊正版官网入口_比漫熊漫画官网正版漫画在线阅读地址

    比漫熊正版官网入口_比漫熊漫画官网正版漫画在线阅读地址比漫熊正版官网入口_比漫熊漫画官网正版漫画在线阅读地址比漫熊正版官网入口_比漫熊漫画官网正版漫画在线阅读地址比漫熊正版官网入口_比漫熊漫画官网正版漫画在线阅读地址

    比漫熊漫画官网入口为https://www.bimanxiong.com,平台涵盖恋爱、悬疑等多种题材,每日更新连载,提供高清画质与简洁界面,支持分类筛选、夜间模式及书架收藏,优化阅读体验。 比漫熊漫画官网入口地址在哪里?这是不少网友都关注的,接下来由PHP小编为大家带来比漫熊漫画官网在线阅读入口地…

    2026年9月24日 用户投稿
    700
  • sublime怎么完全重置到初始状态_sublime恢复默认配置的步骤

    sublime怎么完全重置到初始状态_sublime恢复默认配置的步骤sublime怎么完全重置到初始状态_sublime恢复默认配置的步骤sublime怎么完全重置到初始状态_sublime恢复默认配置的步骤sublime怎么完全重置到初始状态_sublime恢复默认配置的步骤

    完全重置Sublime Text需先关闭程序,再删除系统中的Data目录:Windows路径为C:Users用户名AppDataRoamingSublime TextData,macOS为~/Library/Application Support/Sublime Text/Data,Linux为~/…

    2026年9月24日 用户投稿
    300
  • JFugue中和弦解析的深度解析与实践

    JFugue中和弦解析的深度解析与实践JFugue中和弦解析的深度解析与实践JFugue中和弦解析的深度解析与实践JFugue中和弦解析的深度解析与实践

    JFugue库的onChordParsed方法不会被调用,因为JFugue将和弦分解为独立的音符进行处理。本文详细阐述了如何通过onNoteParsed方法结合音符的isFirstNote(), isHarmonicNote(), isMelodicNote()属性来识别Staccato字符串中的和…

    2026年9月24日 用户投稿
    100
  • 公众号文章如何插入小程序_在文章中插入小程序的正确操作方法

    公众号文章如何插入小程序_在文章中插入小程序的正确操作方法公众号文章如何插入小程序_在文章中插入小程序的正确操作方法公众号文章如何插入小程序_在文章中插入小程序的正确操作方法公众号文章如何插入小程序_在文章中插入小程序的正确操作方法

    可通过图文编辑器插入小程序卡片,设置封面标题及路径;或将小程序链接设为“阅读原文”跳转目标;也可通过自定义菜单关联小程序并引导用户点击;对于无法使用插件的情况,可生成小程序码图片嵌入文章,配以“长按识别”提示语。 如果您希望在公众号文章中增加互动性或引导用户使用特定功能,可以通过插入小程序来实现。小…

    2026年9月24日 用户投稿
    100
  • 怎么在mysql中创建一个表 mysql新建数据表步骤教程

    在 mysql 中创建表的步骤和建议包括:1. 明确业务需求,设计表结构;2. 使用 create table 语句创建表,选择合适的数据类型和设置主键、索引;3. 考虑大数据量时使用分区;4. 设置正确的字符集和排序规则;5. 谨慎使用索引;6. 使用 if not exists 避免重复创建表。…

    2026年9月24日
    100
  • 百度搜索app如何设置默认搜索引擎_百度搜索app搜索引擎切换的详细步骤

    百度搜索app如何设置默认搜索引擎_百度搜索app搜索引擎切换的详细步骤百度搜索app如何设置默认搜索引擎_百度搜索app搜索引擎切换的详细步骤百度搜索app如何设置默认搜索引擎_百度搜索app搜索引擎切换的详细步骤百度搜索app如何设置默认搜索引擎_百度搜索app搜索引擎切换的详细步骤

    百度App不支持更换默认搜索引擎,用户需通过系统浏览器或第三方浏览器设置。首先检查百度App内“我的-设置”是否有搜索引擎选项;若无,可进入手机系统设置中修改默认浏览器的搜索引擎;或下载如Kiwi Browser、Firefox等支持自定义搜索引擎的浏览器,将其默认搜索设为百度,实现灵活搜索体验。 …

    2026年9月24日 用户投稿
    000
  • Spring Boot @Nested 测试中属性覆盖与隔离策略

    Spring Boot @Nested 测试中属性覆盖与隔离策略Spring Boot @Nested 测试中属性覆盖与隔离策略Spring Boot @Nested 测试中属性覆盖与隔离策略Spring Boot @Nested 测试中属性覆盖与隔离策略

    本文深入探讨了在Spring Boot集成测试中,如何利用@Nested注解结合@TestPropertySource实现细粒度的属性配置和隔离。通过详细的示例代码,展示了外部测试类和嵌套测试类如何定义各自的属性集,以及这些属性在不同测试上下文中的继承与覆盖机制,从而确保测试环境的精确控制和独立性。…

    2026年9月24日 用户投稿
    100
  • 2025拼多多双11力度大吗?2025拼多多新版本

    2025拼多多双11力度大吗?2025拼多多新版本2025拼多多双11力度大吗?2025拼多多新版本2025拼多多双11力度大吗?2025拼多多新版本2025拼多多双11力度大吗?2025拼多多新版本

    拼多多2025年双11延续低价策略,升级百亿补贴、推出超级拼团2.0、发放直播神券、启用AR购物空间并扩容会员特权,覆盖iPhone、家电、美妆等品类,叠加多重优惠与互动玩法提升用户体验。 如果您计划在2025年双11期间购物,可能会关注拼多多此次大促的优惠幅度是否足够吸引人。今年拼多多延续了其“低…

    2026年9月24日 用户投稿
    000

发表回复

登录后才能评论
关注微信