实例讲解YII2中多表关联的使用方法


Posted in PHP onJuly 21, 2017

前言

本文对 YII2.0 的多表关联查询做一个简单的介绍。文中通过实例代码介绍的非常详细,下面话不多说,来一起看看详细的介绍:

首先先来说明一下表结构

表结构

现在有订单表、用户表、商品清单表、商品库存表

实例讲解YII2中多表关联的使用方法

实例讲解YII2中多表关联的使用方法

在YII中,如果想直接关联其他表进行查询的话,需要先在模型里定义它们的关联

Order

class Order extends \yii\db\ActiveRecord.{
 
 // 关联函数以get+要关联的数据表名来命名
 // 这是获取下订单的客户
 public function getUser(){
  
  // 第一个参数为要关联的子表模型类名,
  // 第二个参数指定 通过子表的user_id,关联主表的usesr_id字段
  // 这里写清楚点大概意思就是User.user_id => Order.user_id
 return $this->hasMany(User::className(), ['user_id' => 'user_id']);
 }
}

1、hasMany、hasOne使用

Yii2中的表之间的关联有2种,它们用来指定两个模型之间的关联。

      ●一对多:hasMany ●一对一:hasOne

      ●返回结果:这两个方法的返回结果都为yiidbActiveQuery对象(如果你想最后返回的是标准数组形式,记得加上asArray()参数)

      ●第一个参数:所关联的模型的类名称。

      ●第二个参数:是一个数组,其中键为所关联的模型中的属性,值为当前模型中的属性。

关联的使用

现在我们来尝试获取一个订单

//获取订单信息
$order = Order::findOne(1);
//根据订单信息获取到用户信息
$user = $order->user;

当然你可以选择使用with方法,这样看起来简洁一些,其中with的参数为关系的名称,也就在model里面定义的getUser中的user.

//返回订单信息(包括用户信息)
$order = Order::find(1)->with('user');
//或者
$order = Order::find(1)->getUser();

上面的代码会生成并执行如下的sql语句

SELECT * FROM order WHERE id=1;
SELECT * FROM user  WHERE user.user_id=order.user_id;

从上面可以看出访问一个关联的时候有两种方法

       ●如果以函数的方式调用,会返回一个 ActiveQuery 对象($customer->getOrders()->all())

       ●如果以属性的方式调用,会直接返回模型的结果($customer->orders)

关联结果缓存

如果这时order表发生了改变,我们希望再次查询的话

$user = $order->user;

再次得到订单的时候你会发现没有变化。原因是只会在第一次执行$order->user的时候才会去数据库里面查询,然后会把结果缓存起来,以后查询的时候都不会再执行sql。

那么如果你想再次执行sql如何做呢?可以执行

//先释放缓存
unset($order->user);
$order->user;

跨表查询

下面重点来了!通过上面表结构的图可以看到,User表和Order_goods表示没有直接关联的,那么如果我们想根据用户信息查找这个用户买了哪些商品的话,就势必需要通过Order表去关联两张表。那么该怎么做呢?首先还是model层。因为我们是根据用户去查,所以到User的model层去定义关联。

User

public function getOrder() {
 return $this->hasMany(Order::className(), ['user_id' => 'user_id']);
}
 
public function getOrderGoods() {
 return $this->hasMany(OrderGoods::className(), ['order_id' => 'order_id'])->
  via('order');
}

这里注意:getOrderGoods中的第二个order_id是指getOrder关联的Order中的order_id,第一个order_id是指OrderGoods中的order_id。

但是!我们还有最简单的方法,那就是使用SQL语句啦!

$map = 'select
  user.name,
  order.id,
  order_goods.goods_id,
  goods.goods_name,
  stock.stock_count
  from user
  LEFT JOIN order   ON order.user_id = user.user_id
  LEFT JOIN order_goods ON order_goods.order_id = order.order_id
  LEFT JOIN goods   ON goods.goods_id = order_goods.goods_id
  LEFT JOIN stock   ON stock.goods_id = goods.goods_id';

$list1 = Article::findBySql($map)->asArray()->all();

这样基本就是整个关联部分了

总结

以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
PHP原生模板引擎 最简单的模板引擎
Apr 25 PHP
thinkPHP的Html模板标签使用方法
Nov 13 PHP
Codeigniter框架实现获取分页数据和总条数的方法
Dec 05 PHP
linux中cd命令使用详解
Jan 08 PHP
php使用curl获取https请求的方法
Feb 11 PHP
PHP扩展开发入门教程
Feb 26 PHP
PHP中preg_match函数正则匹配的字符串长度问题
May 27 PHP
php.ini中date.timezone设置详解
Nov 20 PHP
ThinkPHP下表单令牌错误与解决方法分析
May 20 PHP
PHP更安全的密码加密机制Bcrypt详解
Jun 18 PHP
thinkPHP5实现的查询数据库并返回json数据实例
Oct 23 PHP
TP - 比RBAC更好的权限认证方式(Auth类认证)
Mar 09 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
Jul 21 #PHP
php实现基于pdo的事务处理方法示例
Jul 21 #PHP
php基于自定义函数记录log日志方法
Jul 21 #PHP
解决form中action属性后面?传递参数 获取不到的问题
Jul 21 #PHP
PHP实现的redis主从数据库状态检测功能示例
Jul 20 #PHP
PHP实现的mysql主从数据库状态检测功能示例
Jul 20 #PHP
php检测mysql表是否存在的方法小结
Jul 20 #PHP
You might like
SONY ICF-SW07收音机电路分析
2021/03/02 无线电
Cakephp 执行主要流程
2010/03/24 PHP
PHP APC配置文件2套和参数详解
2014/06/11 PHP
Laravel模板引擎Blade中section的一些标签的区别介绍
2015/02/10 PHP
php如何实现只替换一次或N次
2015/10/29 PHP
浅析php-fpm静态和动态执行方式的比较
2016/11/09 PHP
两种简单实现菜单高亮显示的JS类代码
2010/06/27 Javascript
javascript中类的定义及其方式(《javascript高级程序设计》学习笔记)
2011/07/04 Javascript
input 输入框获得/失去焦点时隐藏/显示文字(jquery版)
2013/04/02 Javascript
node.js中的events.EventEmitter.listenerCount方法使用说明
2014/12/08 Javascript
jQuery实现首页图片淡入淡出效果的方法
2015/06/10 Javascript
jQuery validate 验证radio实例
2017/03/01 Javascript
Vue 项目部署到服务器的问题解决方法
2017/12/05 Javascript
JavaScript学习总结(一) ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)
2018/01/07 Javascript
微信小程序 wepy框架与iview-weapp的用法详解
2019/04/10 Javascript
[01:02:17]2014 DOTA2华西杯精英邀请赛 5 24 DK VS VG
2014/05/26 DOTA
[01:14:41]DOTA2-DPC中国联赛定级赛 iG vs Magma BO3第一场 1月8日
2021/03/11 DOTA
python返回昨天日期的方法
2015/05/13 Python
tensorflow实现对图片的读取的示例代码
2018/02/12 Python
Django配置celery(非djcelery)执行异步任务和定时任务
2018/07/16 Python
Python中的函数式编程:不可变的数据结构
2018/10/08 Python
python 一维二维插值实例
2020/04/22 Python
python中如何写类
2020/06/29 Python
Python 下载Bing壁纸的示例
2020/09/29 Python
HTML5实现表单自动验证功能实例代码
2017/01/11 HTML / CSS
如何让IE9以下版本(ie6/7/8)认识html5元素
2013/04/01 HTML / CSS
T3官网:头发造型工具
2019/12/26 全球购物
飞利浦西班牙官方网站:Philips西班牙
2020/02/17 全球购物
请说出这段代码执行后a和b的值分别是多少
2015/03/28 面试题
忠诚奉献演讲稿
2014/09/12 职场文书
房产协议书范本
2014/10/18 职场文书
先进单位事迹材料
2014/12/25 职场文书
关于车尾的标语大全
2015/08/11 职场文书
在JavaScript中如何使用宏详解
2021/05/06 Javascript
SpringBoot实现quartz定时任务可视化管理功能
2021/08/30 Java/Android
Javascript之datagrid查询详解
2021/09/15 Javascript