如何将MySQL附近查询转换为Laravel API查询?
把MySQL附近查询转换为Laravel查询构建器代码
没问题,我来帮你把这段在phpMyAdmin里正常运行的MySQL附近查询转换成Laravel的查询构建器代码——核心就是把复杂的距离计算逻辑正确嵌入,同时用更安全的参数绑定替代原SQL里的会话变量,避免直接拼接字符串带来的风险。
原SQL逻辑回顾
你原来的SQL是先设置经纬度会话变量,然后计算每个party到该点的距离,按距离排序取前5条:
set @lat=37.034126; set @lng=27.430235; SELECT party_title, latitude, longitude, 111.045 * DEGREES(ACOS(COS(RADIANS(@lat)) * COS(RADIANS(latitude)) * COS(RADIANS(longitude) - RADIANS(@lng)) + SIN(RADIANS(@lat)) * SIN(RADIANS(latitude)))) AS distance_in_km FROM parties ORDER BY distance_in_km ASC LIMIT 0,5
Laravel 实现方式(两种可选)
方式1:使用DB门面直接操作表
适合没有对应模型的场景,或者需要直接操作表的情况:
$targetLat = 37.034126; $targetLng = 27.430235; $nearbyParties = DB::table('parties') // 用selectRaw写入原生的距离计算表达式,用?作为参数占位符 ->selectRaw( 'party_title, latitude, longitude, 111.045 * DEGREES(ACOS(COS(RADIANS(?)) * COS(RADIANS(latitude)) * COS(RADIANS(longitude) - RADIANS(?)) + SIN(RADIANS(?)) * SIN(RADIANS(latitude)))) AS distance_in_km', [$targetLat, $targetLng, $targetLat] // 按顺序传递参数 ) ->orderBy('distance_in_km', 'asc') ->limit(5) ->get();
方式2:使用Eloquent模型(推荐)
如果你已经有对应parties表的Eloquent模型(比如App\Models\Party),可以直接用模型查询:
use App\Models\Party; $targetLat = 37.034126; $targetLng = 27.430235; $nearbyParties = Party::selectRaw( 'party_title, latitude, longitude, 111.045 * DEGREES(ACOS(COS(RADIANS(?)) * COS(RADIANS(latitude)) * COS(RADIANS(longitude) - RADIANS(?)) + SIN(RADIANS(?)) * SIN(RADIANS(latitude)))) AS distance_in_km', [$targetLat, $targetLng, $targetLat] ) ->orderBy('distance_in_km', 'asc') ->limit(5) ->get();
关键说明
- 参数绑定替代会话变量:原SQL里的
@lat和@lng被替换成了Laravel的参数占位符?,并通过数组传递参数,这样既避免了SQL注入风险,也不需要手动设置MySQL会话变量。 - selectRaw的作用:因为距离计算是复杂的原生SQL表达式,不能用普通的
select()方法,必须用selectRaw()来直接嵌入原生SQL逻辑。 - 扩展:过滤特定距离内的结果:如果需要只返回比如10公里以内的party,可以在查询中添加
havingRaw:
->havingRaw('distance_in_km < ?', [10])
为什么你之前可能转换失败?
大概率是这两个原因:
- 直接把
@lat这类会话变量写到了Laravel的查询里,Laravel的查询构建器会对这类字符做转义,导致逻辑失效; - 用了普通的
select()而不是selectRaw()来处理复杂的距离计算表达式,导致Laravel无法正确解析SQL逻辑。
内容的提问来源于stack exchange,提问作者Baran KARABOGA
相关产品推荐
相关产品推荐

