Laravel 的关联模型 及其 预加载with应用( 附TP5的)

预加载 关联模型 和 TP 一样 都是用with model 关联定义 大同小异

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    /**
     * 获取书籍作者。
     */
    public function author()
    {
        return $this->belongsTo('App\Author');
    }
}


//控制器
$books = App\Book::with('author')->get();

foreach ($books as $book) {
    echo $book->author->name;
}

预加载多个关联 有时,你可能需要在单一操作中预加载几个不同的关联。要达成此目的,只要向 with 方法传递多个关联名称构成的数组参数:

$books = App\Book::with(['author', 'publisher'])->get();

嵌套预加载 可以使用 「点」 语法预加载嵌套关联。比如在一个 Eloquent 语句中预加载所有书籍作者及其联系方式:

$books = App\Book::with('author.contacts')->get();

预加载指定列 并不是总需要获取关系的每一列。在这种情况下,Eloquent 允许你为关联指定想要获取的列:

$users = App\Book::with('author:id,name')->get();

注意:在使用这个特性时,一定要在要获取的列的列表中包含 id 列。

为预加载添加约束 有时,可能希望预加载一个关联,同时为预加载查询添加额外查询条件,就像下面的例子:

$users = App\User::with(['posts' => function ($query) {
    $query->where('title', 'like', '%first%');
}])->get();

在这个例子中, Eloquent 将仅预加载那些 title 列包含 first 关键词的文章。也可以调用其它的 查询构造器 方法进一步自定义预加载操作:

$users = App\User::with(['posts' => function ($query) {
    $query->orderBy('created_at', 'desc');
}])->get();

注意:在约束预加载时,不能使用 limit 和 take 查询构造器方法。

以上来自官方文档

具体使用

model中定义方法(user)
 public function getRole(){
        $data = $this->hasOne(Roles::class,"id(role中的id)","rolle_id(user中的)");
        return $data;
    }
    其他地方使用这个方法
    Users::with('getRole:id,name')->get(['name','role_id'])->toArray();
    //with里面对于role表而言,get对于users
Laravel 中预加载指定查询字段
直接上代码

$result = User::with('topics:user_id,body,title')
    ->where('name', 'Summer')
    ->get()
    ->toArray();


如果要进行约束预加载,应该这样写。

$result = User::with(['topics' => function ($query) {
    $query->select('id', 'user_id', 'body', 'title')
        ->orderBy('updated_at', 'desc');
    }])
    ->where('name', 'Summer')
    ->get()
    ->toArray();

在使用预加载时,表的关联字段一定要查询,否则查询后的数据没法匹配

另附 laravel 和 tp的 一些差异

1.0 Laravel 在表单提交的时候会有csrf 跨站请求伪造验证,Tp5则没有。

2.0 Laravel 在请求需要先定义路由,Tp5可以不定义,有pathinfo路由即可访问。

3.0 Laravel 在请求之前会有中间件, Tp5会有前置操作和钩子。

###TP5里的 主要看逻辑构思 不看语法 首先我们用ORM(Object Relation Mapping) 对象关系映射 然后优先考虑静态方法 返回的都是当前模型的对象实例

1.首先查询

是用到最多的(而且难免会有复杂的查询条件或者需要实现的查询): 再定义好模型的关联后 我们最常用的应该就是用with了 那么接受参数可以是字符串 或者 数组的形式

1.1.with

字符串形式XxModel::with('items,items.img') 嵌套关系用.分隔 注意只有一对引号 中间是用逗号隔开关联方法 数组的形式XxModel::with(['items','items.img'])推荐使用数组 当然如果只有一个关联方法就用字符串 简洁可读性更好 当然with 最后需要用select 或者 find收尾 完整的例子如下self::with(['items','items.img'])->find($id);

一些复杂的 关联模型查询用法:

对当前模型用limit 和 order self::limit($count) ->order('create_time desc') ->select(); 对关联模型(并且是多重嵌套的话)进行order?闭包形式? self::with([ 'imgs' => function($query){ $query->with(['imgUrl']) ->order('order asc'); } ]) ->with('xxx') ->find('xid'); 其中imgs是关联方法1 imgUrl是关联后的模型的关联方法(A->B->C表) 后面使用闭包进行排序 然后就可以举一反三了 常用的修饰方法还有 visable() hidden() 如果是数据集 还可以用toArray转数组 具体可以看框架源代码查找

1.2 all

顾明思意 是查找全部 当XxModel::all([],[]) 第一个参数如果传空 代表查全部 如果传数组 那么就查指定的数据 如['name'=>'张三','name'=>'李四'] 当然如果是传主键id 可以直接是[1,2,3] 这样子 第二个参数用法跟用with里的参数一致 说白了就是 with+select 的升级版 select 和 find 是基本用法如下不过多赘述 XxModel::with('xxx')->select([1,2,3]); XxModel::with('xxx')->find(2); 关于get这个方法 get方法仅仅会用在当前模型直接去一个数据 然后就没然后了 要取关联模型的数据还是需要配合with + select或find

select查询出的是多条数据,转成数组后可以在模版volist循环打印出来 find和get获取单条数据,可直接在模版打印;

find 或者get返回的是 当前模型的对象实例 然后模型的all方法或者select方法返回的是一个包含模型对象的二维数组或者数据集对象

本模型分页: Xxmodle->where() ->paginate($size,true,['page'=>$page]); 第二个参数true为简洁模式 测试发现paginate取得的数据不受配置文件 配置成数据集对象 这里依然是数组对象 所以可能需要$collection=collection($data->items());进行转换

# 2.新增和修改

单模型新增:模型的静态方法create 直接新增到当前模型? XxModel::create([ 'name' => '哈哈哈' ]); 返回新增的实例对象 比如可以用$res->id取id

单模型修改:update 直接修改当前的关联模型? XxModel::where('id', 1) ->update(['name' => '哦哦哦']);

对于关联模型的新增和修改? 关联新增 $user = User::get(1); // 如果还没有关联数据 则进行新增 $user->profile()->save(['email' => 'thinkphp']); 系统会自动把当前模型的主键传入profile模型。

关联更新 和新增一样使用save方法进行更新关联数据。 $user = User::get(1); $user->profile->save(['email' => 'thinkphp']); **区别在于新增的关联方法profile 带一个括号 而新增则无 **

本模型某字段的的加减 XxModel::where('id', 1) ->setDec('字段名','减少数值');

TP5里的 一对多 一对一

首先看这个理解:一对一关联模型的理解 首先我们要知道 一对一 两者并不是对等的关系 到底用那个 看业务情况 比如AB 2个表 A表存有B表的外键 B表没有A表的外键 那么如果业务是查A表 那么我们就查A表 用belongsTo去关联B表 反之如果当前业务在查B表 那么我们用hasOne去关联A表

hasMany 是一对多 belongsToMany 是多对多

然后再用self::with()方法封装在自定义方法里好后 控制器里面调用自定义模型方法即可

关于with的参数语法 with('关联方法1,关联方法2,...') 注意是只有一组分号 另外一种是接受数组 主要解决嵌套关系(查询AB表数据后 B的数据结果再去查C中的数据) 语法是参数变数组然后如下 with(['关联方法AB',['关联方法AB.关联方法BC']]) 注意是数组

记录你我
请先登录后发表评论
  • latest comments
  • 总共0条评论