我通过雄辩的关系发现一种奇怪的行为。
我写了这个简单的测试:
Route::get('/myTest', function () {
$book = \App\Models\BookModel::findOrFail(7);
$count_start = 1;
$count_end = 3;
while ($count_start <= $count_end) {
\Log::info(' A');
$position = $book->position->name;
\Log::info(' B');
sleep(5);
$count_start++;
}
});
日志转发:
[2019-07-09 13:40:04] - INFO: A
[2019-07-09 13:40:04] - DEBUG: query: {"sql":"select * from `position` where `position`.`fk_book` = ? limit 1","time":4.66,"bindings":[7]}
[2019-07-09 13:40:04] - INFO: B
[2019-07-09 13:40:09] - INFO: A
[2019-07-09 13:40:09] - INFO: B
[2019-07-09 13:40:14] - INFO: A
[2019-07-09 13:40:14] - INFO: B
奇怪的行为是,该过程首次进入while
时,查询被正确执行;第二次和第三次(5秒后)查询不再执行,我也不明白为什么!
这正常吗?为什么关系查询仅在第一次执行?
谢谢。
答案 0 :(得分:0)
您初始化
$couny_end = 3;
但在$count_end
中使用for
:
while ($count_start <= $count_end && $position == false) {
//...
}
$count_end
是虚假的,并且在第一次迭代之后$position
将不再是false
。
答案 1 :(得分:0)
一旦加载,Laravel将缓存关系值,因为大多数用例不需要每次访问该属性时都重新加载。
如果您想强制它重新加载关系,可以致电$book->load('position')
答案 2 :(得分:0)
在Laravel中,关系被缓存。
首次访问$book->position
时,它会执行查询,因为还没有position
模型。执行查询后,position
模型将附加到$book
对象。因此,随后对$book->position
的每次调用都将使用该对象,而不会触发新的数据库查询。
这是默认的行为,但是您可以利用Laravel来完成所需的任何操作。
如果要在单个查询中加载具有关系的模型(对大量对象有用),可以急于加载它:
$book = BookModel::with('position')->findOrFail(7); // $book->position is immediately populated
如果需要在已缓存数据时强制执行新查询,则需要访问和查询关系:
$position = $book->position()->first(); // Force the execution of a new query
或
$book->load('position');