ThinkPHP5 Model关联查询返回指定字段
ThinkPHP5 Model关联查询返回指定字段
如题,我在写一个接口时需要用到关联查询,因为对ThinkPHP5 不熟悉,去查询官方文档,使用belongsTo 指定关联模型,然后写出查询语句是这样子的:
public static function getMessageListByPage($pageno, $rows) { $ruleList = []; //with 关联预载入 $ruleList = collection(self::with('user') ->order('updatetime desc') ->page($pageno.','.$rows) ->field('uid, lastmessage, readstatus, file, appid') ->select())->toArray(); return $ruleList; } //关联方法的使用 //has_one(或has_many):外键在子关联对象中 //belongs_to:外键在父联对象中 //当有大量的关联数据需要查询的时候,一般都会考虑选择关联预载入的方式 //预载入方法定义 public function user() { // setEagerlyType设置预载入查询方式为 0 为 JOIN 1为 IN return $this->belongsTo('User', 'uid', 'id', [], 'LEFT') ->field('email') ->setEagerlyType(0); }
这是一个最新消息列表的分页查询,我想在每条消息上附带上用户邮箱,就是email字段
查询结果如下 :
[ { "uid":45, "readstatus":0, "lastmessage":"0", "file":0, "createtime":0, "updatetime":0, "appid":0, "user":{ "id":45, "group_id":3, "email":"xxxxxxxx@qq.com", "password":"xxxxxxxxxxxxx", "xxx":"xxxx" } }]
虽然成功带上了email 字段,但是却是在user 属性里面,并且整个查询把user 表的所有字段都返回了,field方法对belongsTo 关联不起作用.这肯定不符合我的预期啊
于是乎遇事不决看文档,文档说可以使用bind()
方法指定查询字段,该方法支持数组,以下为官方文档:
绑定属性到父模型(V5.0.4+)
可以在定义关联的时候使用bind方法绑定属性到父模型,例如:
<?phpnamespace app\index\model;use think\Model;class User extends Model { public function profile() { return $this->hasOne('Profile','uid')->bind('nickname,email'); }}//或者使用数组的方式指定绑定属性别名<?phpnamespace app\index\model;use think\Model;class User extends Model { public function profile() { return $this->hasOne('Profile','uid')->bind([ 'email', 'truename'=> 'nickname', 'profile_id' => 'id', ]); }}
于是我就加上了bind
方法,指定返回email字段:
public static function getMessageListByPage($pageno, $rows) { $ruleList = []; //with 关联预载入 $ruleList = collection(self::with('user') ->order('updatetime desc') ->page($pageno.','.$rows) ->field('uid, lastmessage, readstatus, file, appid') ->select())->toArray(); return $ruleList; } //关联方法的使用 //has_one(或has_many):外键在子关联对象中 //belongs_to:外键在父联对象中 //当有大量的关联数据需要查询的时候,一般都会考虑选择关联预载入的方式 //预载人方法定义 public function user() { // setEagerlyType设置预载入查询方式为 0 为 JOIN 1为 IN return $this->belongsTo('User', 'uid', 'id', [], 'LEFT') ->bind('email') ->setEagerlyType(0); }
然后查询结果如下:
[ { "uid":45, "readstatus":0, "lastmessage":"0", "file":0, "createtime":0, "updatetime":0, "appid":0, "email":"xxxxxxxx@qq.com", "user":{ "id":45, "group_id":3, "email":"xxxxxxxx@qq.com", "password":"xxxxxxxxxxxxx", "xxx":"xxxx" } }]
坑爹呢,email字段是有了,但是user表的所有字段还是被查询出来了,连密码都查出来了,用脚趾头想也知道这指定不符合我的初衷,于是乎继续看文档,但是文档对这块介绍不多,我注意到文档里一句话
绑定关联属性不影响原有关联属性的读取,绑定关联模型的属性支持读取器。
所以说其实bind
方法不会影响关联属性,也就是查询后附加的user 模型对象
得嘞,去百度看看还有没有其他解决办法,果然找到一个 fastadmin 社区帖子
他给出的解决方法是:
//with的时候使用闭包查询 ->with([ 'account' => function ($query) { $query->withField('id,user_id,account,frozen'); }, ])
于是乎我再次去修改查询方法,加入闭包指定返回email字段:
public static function getMessageListByPage($pageno, $rows) { $ruleList = []; //with 关联预载入 $ruleList = collection(self::with( ['user' => function($query){ $query->withField(['email']); }]) ->order('updatetime desc') ->page($pageno.','.$rows) ->field('uid, lastmessage, readstatus, file, appid') ->select())->toArray(); return $ruleList; } //关联方法的使用 //has_one(或has_many):外键在子关联对象中 //belongs_to:外键在父联对象中 //当有大量的关联数据需要查询的时候,一般都会考虑选择关联预载入的方式 //预载人方法定义 public function user() { // setEagerlyType设置预载入查询方式为 0 为 JOIN 1为 IN return $this->belongsTo('User', 'uid', 'id', [], 'LEFT') ->bind(['email' => 'email',]) ->setEagerlyType(0); }
查询结果为:
[ { "uid":45, "readstatus":0, "lastmessage":"0", "file":0, "createtime":0, "updatetime":0, "appid":0, "email":"xxxxxxxx@qq.com", "user":{ "email":"xxxxxxxx@qq.com", } }]
貌似达到了预期的效果,但是还是会多出user这个属性,先凑合着用吧.
我想到的是自己再做一次循环数据处理将user去除,但是觉得应该还有更优雅的方法,记录下来找到合适的方式再更新,
来源地址:https://blog.csdn.net/NidhoogJX/article/details/128496087
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341