我会构造一个业务场景,主要是测试我比较存疑的各种表关联写法,而非再次介绍基础用法。
构造场景
订单ar_order
order_id | 订单id(主键) |
user_id | 用户id |
用户ar_user
user_id | 用户id(主键) |
user_name | 用户名 |
订单商品清单ar_order_goods
id | 自增id(主键) |
order_id | 所属订单id |
goods_id | 所买商品id |
商品ar_goods
goods_id | 商品id(主键) |
goods_name | 商品名称 |
商品库存ar_stock
stock_id | 库存id(主键) |
goods_id | 商品id(唯一键) |
stock_count | 库存量 |
表关系如下图所示:
我们接下来的测试,均以"订单"为主体,通过AR的ORM关联来查询出依赖的数据。
环境准备
除了建表,还需要用gii生成所有的AR类,另外日志至少需要开启db相关的category才能在日志里看见执行的SQL是什么。
1
2
3
4
5
6
7
8
9
10
|
'log'
=> [
'traceLevel'
=> YII_DEBUG ? 3 : 0,
'targets'
=> [
[
'class'
=>
'yii\log\FileTarget'
,
'levels'
=> [
'info'
,
'error'
,
'warning'
,
'trace'
],
'categories'
=> [
'yii\db\*'
],
],
],
],
|
简单关联
订单与用户 1:1
数据:
ar_order:
ar_user:
给ArOrder添加关联:
1
2
3
|
public
function
getUser() {
return
$this
->hasOne(ArUser::className(), [
'user_id'
=>
'user_id'
]);
}
|
测试lazyload:
1
2
3
4
5
6
7
8
9
10
11
|
public
function
actionHasOne()
{
// 查订单
$orders
= ArOrder::find()->all();
foreach
(
$orders
as
$order
) {
// 查订单关联的用户
$user
=
$order
->user;
// 打印用户名
echo
$user
->user_name . PHP_EOL;
}
}
|
lazyload sql:
1
2
3
4
5
|
SELECT * FROM ar_order
SELECT * FROM `ar_user` WHERE `user_id`=1
SELECT * FROM `ar_user` WHERE `user_id`=2
|
测试eagerload:
1
2
3
4
5
6
7
8
9
10
11
|
public
function
actionHasOne()
{
// 查订单
$orders
= ArOrder::find()->with(
'user'
)->all();
foreach
(
$orders
as
$order
) {
// 查订单关联的用户
$user
=
$order
->user;
// 打印用户名,输出:owen
|