php 5.5链接数据表,php – Laravel 5如何使用链接检索相关的表数据

我有区域(城市列表),租赁(租赁信息列表)和Rental_Location(租赁地址列表/长)的数据库表.

基本关系是:

Regions haveMany Rentals (with FK's region_id and rental_location_id in Rentals table)

Locations haveMany Rentals, or the reverse logic Rental belongsTo a Location

我想要做的是从region_id(来自租赁表)获取区域中所有租赁的位置信息,以及包括位置空间数据(rental_locations表):

$region = Region::find(1);

$rentals = $region->rentals; // doesn't contain location information yet

$rentalDataWithSpatialLocationData = $region->rentals->location; // what I liked to do

但是使用belongsTo关系的最后一行将无法通过将rental_locations中的空间数据添加到原始租赁集合中.

现在$rental集合包含一个区域的所有租赁,但没有空间数据来标记地图上的位置,但除了在QueryBuilder中使用如下所示的连接而不在我的模型中使用ORM hasMany属性:

$spatials = DB::table('rentals')

->join('regions', 'rentals.region_id', '=', 'regions.id')

->join('rental_locations', 'rentals.rental_location_id', '=', 'rental_locations.id')

->where('rentals.region_id', '=', $region_id)

->select('*')

->get();

基本上,我无法弄清楚如何使用其位置信息获取所有租赁的集合,这是否可以使用ORM?看起来这样比连接可能会变得昂贵,所以我现在假设您不使用ORM来排除QueryBuilder,而只是补充简单和快速的关系查询?

解决方法:

这里有几件你应该知道的事情.

首先,对于您的原始问题,您的代码将无法运行,因为您尝试访问租赁模型集合上的关系属性,而不是单个模型.如果您遍历集合,您将能够很好地访问每个单独项目上的位置关系:

$region = Region::find(1);

$rentals = $region->rentals; // Collection of rentals for the region

foreach($rentals as $rental) {

print_r($rental->location); // location info for the individual rental

}

现在,有关上述代码的一点需要注意的是,您将遇到所谓的N 1问题.默认情况下,Laravel延迟加载关系对象,因此在需要关系属性之前,不会运行填充关系数据的查询.暂时忽略该区域,在上面的代码中,Laravel将运行一个查询以获取所有租借,然后在foreach循环中,它将为每个循环迭代(N个查询)运行新查询以获取位置信息每次出租;因此N 1查询.

要缓解此问题,您可以急切加载关系.通过急切加载,Laravel将运行一个查询来获取租金,然后一个查询获取所有租赁的所有位置信息,总共两个查询(而不是N 1).将区域信息重新放回那里,实际上是三个查询.

要急切加载关系,可以在查询中使用with()方法:

// eager load the rentals, and the nested location on the rentals

// 1 query for region, 1 for all rentals on region, and 1 for all locations on rentals

$region = Region::with('rentals', 'rentals.location')->find(1);

// this is now accessing already loaded rentals; no lazy loading needed

$rentals = $region->rentals;

foreach($rentals as $rental) {

// this is now accessing already loaded locations; no lazy loading needed

print_r($rental->location);

}

这样做的另一个不同之处是,您可能认为自己无法访问位置信息,因为延迟加载的关系在您访问它们之前不会显示,而急切加载的关系立即可用.通过将对象打印到屏幕进行调试时,这可能会让您认为当您真的没有时会丢失数据.我的意思是:

/**

* lazy load relationships

* This will only show the information for the region object. No

* rental or location information will be shown as it has not been

* loaded yet.

*/

$region = Region::find(1);

print_r($region);

/**

* eager load relationships

* This will show the information for the region object, as well as

* all of the related rental objects and their related location

* information.

*/

$region = Region::with('rentals', 'rentals.location')->find(1);

print_r($region);

标签:php,mysql,laravel,laravel-5,eloquent

来源: https://codeday.me/bug/20190609/1203993.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值