Laravel8.0在查询数据库时遇到的问题
2020-10-25 admin laravel mysql 1784
laravel的数据库查询功能是很强大的,不过,今天在使用过程中却遇到了一点小问题,现记录如下 :
一是json字段数组如何查询的问题。使用场景是一个用户账号可以绑定多个微信openid,我们在获取用户openid后,需要判断这个openid在哪个账号中,比如数据如下:
[4,5,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,63,64,65,66,67,68,69,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,96,97,98,99,100,101,102,103,104,105,106,108,109,110,111,112,114,115,116,117,118,120,121,126,127,128,129]
用户openid为5,需要查询这个5是否在上面的json数组字段中,我们按照教程使用以下语句:
->whereJsonContains('openid',$openid)
初次使用,好像没有问题,不过后来发现,丢失了一部分数据,经过仔细排查,原来是字符串和数字类型的查询,会出现两种不同的结果,因此需要修改为以下语句:
->whereJsonContains('openid',(string)$openid) ->orwhereJsonContains('openid',(int)$openid)
这样查询结果就准确了。
二是多个where和orwhere并存时,需要注意顺序。比如类似小学数学的(a or b) and c这种,需要使用闭包来查询,并且闭包要放在前面:
$groupid = ''.Yhz::whereJsonContains('user_id',$userid)->value('id');//获取用户所在的Yhz组id $list = BgwModel::where(function($query) { $query->WhereNull('timing') ->orWhere('timing','<',Carbon::now()->toDateTimeString()); })->whereJsonContains('receive',(string)$groupid) ->orwhereJsonContains('receive',(int)$groupid) ->orwhere('cjz',Admin::user()->username)->latest('updated_at') ->limit(10)->select('id','title','unread')->get()->toArray();
最后,发现在laravel admin中,model加上如上条件后,查询和筛选无效了。可能是条件冲突了。再次修改查询语句如下就正常了:
$grid->model()->where(function($query)use($groupid){ $query->whereJsonContains('receive',(string)$groupid) ->orwhereJsonContains('receive',(int)$groupid) ->orwhere('cjz',Admin::user()->username); })->Where('timing','<',Carbon::now()->toDateTimeString())->orderBy('updated_at','desc');
记录完毕。