关于YII关联查询的解析
这篇文章主要介绍了YII关联查询的相关资料,需要的朋友可以参考下
一、多表关联的配置
在我们使用 AR 执行关联查询之前,我们需要让 AR 知道一个 AR 类是怎样关联到另一个的。
两个 AR 类之间的关系直接通过 AR 类所代表的数据表之间的关系相关联。 从数据库的角度来说,表 A 和 B 之间有三种关系:一对多(one-to-many,例如 tbl_user 和 tbl_post),一对一( one-to-one 例如 tbl_user 和 tbl_profile)和 多对多(many-to-many 例如 tbl_category 和 tbl_post)。 在 AR 中,有四种关系:
BELONGS_TO(属于): 如果表 A 和 B 之间的关系是一对多,则 表 B 属于 表 A (例如 Post 属于 User);
HAS_MANY(有多个): 如果表 A 和 B 之间的关系是一对多,则 A 有多个 B (例如 User 有多个 Post);
HAS_ONE(有一个): 这是 HAS_MANY 的一个特例,A 最多有一个 B (例如 User 最多有一个 Profile);
MANY_MANY: 这个对应于数据库中的 多对多 关系。 由于多数 DBMS 不直接支持 多对多 关系,因此需要有一个关联表将 多对多 关系分割为 一对多 关系。 在我们的示例数据结构中,tbl_post_category 就是用于此目的的。在 AR 术语中,我们可以解释MANY_MANY 为 BELONGS_TO 和 HAS_MANY 的组合。 例如,Post 属于多个(belongs to many) Category ,Category 有多个(has many) Post.
AR 中定义关系需要覆盖 CActiveRecord 中的 relations() 方法。此方法返回一个关系配置数组。每个数组元素通过如下格式表示一个单一的关系。
'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...additional options)
其中 VarName 是关系的名字;RelationType 指定关系类型,可以是一下四个常量之一: self::BELONGS_TO, self::HAS_ONE,self::HAS_MANY and self::MANY_MANY;ClassName 是此 AR 类所关联的 AR 类的名字; ForeignKey 指定关系中使用的外键(一个或多个)。
需要弄清楚的几点:
(1),VarName指什么? 详见下面例2。
(2),RelationType。一共有4种,分别为
self::HAS_MANY, self::BELONGS_TO, self::MANY_MANY, self::HAS_ONE。
(3),ClassName。即关联的另一个../model/类名.php。
(4),ForeignKey。谁是谁的外键?
(5),附加条件
ER Diagram
例1,一对多与多对一关系(post和user之间的关系)
1)models/Post.php
class Post extends CActiveRecord { ...... public function relations() { return array( 'author'=>array(self::BELONGS_TO, 'User', 'author_id'), ); } }
其中Post与User的关系是BELONGS_TO(多对一)关系,并通过Post的author_id与User关联。
Post中author_id是外键,关联到User中。
注:此处的VarName是author,一个对象。
(2)models/User.php
class User extends CActiveRecord { ...... public function relations() { return array( 'posts'=>array(self::HAS_MANY, 'Post', 'author_id'), 'profile'=>array(self::HAS_ONE, 'Profile', 'owner_id'), ); } }
对于User,与Post的关系是属于HAS_MANY(一对多)关系。并通过Post的author_id与Post关联。
例2,多对多关系
在FailParts.php中
'Users' => array(self::MANY_MANY, 'User', 'fail_parts_user(fail_parts_id, user_id)'),
在User.php中
'FailParts' => array(self::MANY_MANY, 'FailParts', 'fail_parts_user(user_id, fail_parts_id)'),
由于两者是多对多关系,所以要用Users,而不是User;要用FailParts,而不是FailPart。
此处的Users和FailParts,即为前面的VarName。
例3,一对一关系
比较简单,暂略。
2,关于VarName。
对于类A.php,'VarName'=>array('RelationType', 'B', 'ForeignKey', ...additional options)
其中VarName与B基本相同。但未必完全一样。此时就可以在A的views/A/xx.php中通过VarName来访问B及其属性值了。
如果是一对一:A->VarName
如果是多对一:author_name = $post->Author->name;
如果是一对多:$posts = $author->Post;
如果是多对多:$posts = $author->Post;//本质是拆成一对多和多对一
foreach($posts as $u){ $_tmp_titles[] = $u -> title; } titleStr = implode(', ', $_tmp_titles);
二、多表关联的使用
常常在controllers里
1,延时加载
(1)多对一
$post = Post::model()->findByPk(10); $author = $post->author;
批注:此处本质是一对一。
(2)一对多
$user = User::model()->findByPk(10); $posts = $user->posts;
(3)多对多
需要重点注意:两个id有先后关系。
站在$repairInfo实例的角度,关联关系必须是
'FailParts' => array(self::MANY_MANY, 'FailParts', 'repair_mapping(repair_info_id,fail_parts_id)'),
而站在$failParts实例的角度,则关联关系变为
'RepairInfos' => array(self::MANY_MANY, 'RepairInfo', 'repair_mapping(fail_parts_id, repair_info_id)'),
而前面也已经指出,不需要双方都配置,只需需要的一方设置即可。
之前曾使用过的笨方法:
/*方法一:使用表关系(多对多)*/ $fails = $repairInfo->FailParts;//在$repairInfo中使用 /*方法二:使用原始方法*/ $id = $repairInfo->id; $maps = RepairMapping::model()->findAll("repair_info_id = $id"); $f_ids = array(); foreach($maps as $map){ array_push($f_ids, $maps[0]->fail_parts_id); } $f_idsStr = implode(',',$f_ids); $fails = FailParts::model()->findAll("id IN ($f_idsStr)");
2,主动加载——with
(1)一对多
(2)多对多
$posts = Post::model()->('author')->findAll();
例子:
User.php
//查询一个机房$idc_id的所有用户 function getAdminedUsersByIdc($idc_id){ $c = new CDbCriteria(); $c->join = "JOIN idc_user on t.id=idc_user.user_id"; $c->condition = "idc_user.idc_id=$idc_id"; return User::model()->with('Idcs')->findAll($c); } //规则中配置 'Idcs' => array(self::MANY_MANY, 'Idc', 'idc_user(user_id, idc_id)'),
批注:没有with('Idcs'),执行后的结果也一样。只不过不再是eager loading。
三、带参数的关联配置
常见的条件有
1,condition 按某个表的某个字段加过滤条件
例如:
//在User的model里定义,如下关联关系 'doingOutsources' => array(self::MANY_MANY, 'Outsource', 'outsource_user(user_id, outsource_id)', 'condition' => "doingOutsources.status_id IN(" . Status::ASSIGNED . "," . Status::STARTED ."," . Status::REJECTED .")"),
//结论:condition是array里指定model的一个字段。
显然,doingOutsources是真实数据表Outsource的别名,所以在condition中可以使用doingOutsources.status_id,当然也可以使用Outsource.status_id。另本表名user的默认别名是t。
2,order 按某个表的某个字段升序或降序
//在RepairInfo的model里定义,如下关联关系 'WorkSheet' => array(self::HAS_MANY, 'WorkSheet', 'repair_info_id', order => 'created_at desc'), //调用 $worksheets = $repair_info->WorkSheet; //此时$worksheets是按降序排列
//结论:order是array里指定model的一个字段。
with
joinType
select
params
on
alias
together
group
having
index
还有用于lazy loading的
limit 只取5个或10个
offset
through
官方手册
'posts'=>array(self::HAS_MANY, 'post', 'author_id', 'order'=>'posts.create_time DESC', 'with'=>'categories'),
四、静态查询(仅用于HAS_MANY和MANY_MANY)
关键字:self:STAT
1,基本用法。例如,
class Post extends CActiveRecord { ...... public function relations() { return array( 'commentCount'=>array(self::STAT, 'Comment', 'post_id'), 'categoryCount'=>array(self::STAT,'Category','post_category(post_id, category_id)'); ); } }
2,静态查询也支持上面的各种条件查询
如
'doingOutsourceCount' => array(self::STAT, 'Outsource', 'outsource_user(user_id, outsource_id)', 'condition' => "outsource.status_id IN(" . Status::ASSIGNED . "," . Status::STARTED ."," . Status::REJECTED .")"),
其他查询还包括
condition 使用较多
order
select
defaultValue
params
group
having
3,静态查询的加载方式
可以使用lazy loading方式
$post->commentCount.
也可以使用eager loading方式
$posts = Post::model()->with('commentCount','categoryCount')->findAll();
注with中字符串一定是别名。
两者的性能比较:
如果需要取所有post的所有comment,前者需要2N+1次查询,而后者只有一次。两者的选择视情况而定。
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
如何实现Yii2框架中使用PHPExcel导出Excel文件
Atas ialah kandungan terperinci 关于YII关联查询的解析. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Penjelasan terperinci tentang konfigurasi pertanyaan satu-ke-banyak MyBatis: Untuk menyelesaikan masalah pertanyaan biasa yang berkaitan, contoh kod khusus diperlukan Dalam kerja pembangunan sebenar, kita sering menghadapi situasi di mana kita perlu menanyakan objek entiti utama dan objek entiti hamba berbilang yang berkaitan. . Dalam MyBatis, pertanyaan satu-ke-banyak ialah pertanyaan perkaitan pangkalan data biasa Dengan konfigurasi yang betul, pertanyaan, paparan dan pengendalian objek yang berkaitan boleh direalisasikan dengan mudah. Artikel ini akan memperkenalkan kaedah konfigurasi pertanyaan satu-ke-banyak dalam MyBatis, dan cara menyelesaikan beberapa masalah pertanyaan biasa yang berkaitan

Dengan perkembangan berterusan teknologi pengkomputeran awan, sandaran data telah menjadi sesuatu yang mesti dilakukan oleh setiap perusahaan. Dalam konteks ini, amat penting untuk membangunkan sistem sandaran awan yang sangat tersedia. Rangka kerja PHP Yii ialah rangka kerja berkuasa yang boleh membantu pembangun membina aplikasi web berprestasi tinggi dengan cepat. Berikut akan memperkenalkan cara menggunakan rangka kerja Yii untuk membangunkan sistem sandaran awan yang sangat tersedia. Mereka bentuk model pangkalan data Dalam rangka kerja Yii, model pangkalan data adalah bahagian yang sangat penting. Kerana sistem sandaran data memerlukan banyak jadual dan hubungan

Kemahiran pertanyaan berkaitan berbilang jadual dalam pertanyaan Berkaitan PHP adalah bahagian penting dalam pertanyaan pangkalan data, terutamanya apabila anda perlu memaparkan data dalam berbilang jadual pangkalan data berkaitan. Dalam aplikasi PHP, pertanyaan berkaitan pelbagai jadual sering digunakan apabila menggunakan pangkalan data seperti MySQL. Maksud perkaitan berbilang jadual ialah membandingkan data dalam satu jadual dengan data dalam jadual lain atau berbilang, dan menyambungkan baris tersebut yang memenuhi keperluan dalam hasilnya. Apabila melakukan pertanyaan korelasi berbilang jadual, anda perlu mempertimbangkan hubungan antara jadual dan menggunakan kaedah korelasi yang sesuai. Berikut memperkenalkan beberapa jenis

Memandangkan permintaan untuk aplikasi web terus berkembang, pembangun mempunyai lebih banyak pilihan dalam memilih rangka kerja pembangunan. Symfony dan Yii2 ialah dua rangka kerja PHP yang popular Kedua-duanya mempunyai fungsi dan prestasi yang berkuasa, tetapi apabila berhadapan dengan keperluan untuk membangunkan aplikasi web berskala besar, rangka kerja manakah yang lebih sesuai? Seterusnya kami akan menjalankan analisis perbandingan Symphony dan Yii2 untuk membantu anda membuat pilihan yang lebih baik. Gambaran Keseluruhan Asas Symphony ialah rangka kerja aplikasi web sumber terbuka yang ditulis dalam PHP dan dibina di atas

Memandangkan Internet terus berkembang, permintaan untuk pembangunan aplikasi web juga semakin tinggi. Bagi pembangun, membangunkan aplikasi memerlukan rangka kerja yang stabil, cekap dan berkuasa, yang boleh meningkatkan kecekapan pembangunan. Yii ialah rangka kerja PHP berprestasi tinggi terkemuka yang menyediakan ciri yang kaya dan prestasi yang baik. Yii3 ialah versi generasi seterusnya bagi rangka kerja Yii, yang seterusnya mengoptimumkan prestasi dan kualiti kod berdasarkan Yii2. Dalam artikel ini, kami akan memperkenalkan cara menggunakan rangka kerja Yii3 untuk membangunkan aplikasi PHP.

Rangka kerja Yii ialah rangka kerja aplikasi Web PHP sumber terbuka yang menyediakan pelbagai alatan dan komponen untuk memudahkan proses pembangunan aplikasi Web, yang mana pertanyaan data merupakan salah satu komponen penting. Dalam rangka kerja Yii, kita boleh menggunakan sintaks seperti SQL untuk mengakses pangkalan data untuk membuat pertanyaan dan memanipulasi data dengan cekap. Pembina pertanyaan rangka kerja Yii terutamanya termasuk jenis berikut: pertanyaan ActiveRecord, pertanyaan QueryBuilder, pertanyaan arahan dan pertanyaan SQL asal

Dalam era maklumat semasa, data besar, kecerdasan buatan, pengkomputeran awan dan teknologi lain telah menjadi tumpuan perusahaan utama. Di antara teknologi ini, teknologi pemaparan kad grafik, sebagai teknologi pemprosesan grafik berprestasi tinggi, telah mendapat perhatian yang lebih. Teknologi pemaparan kad grafik digunakan secara meluas dalam pembangunan permainan, filem dan kesan khas televisyen, pemodelan kejuruteraan dan bidang lain. Bagi pembangun, memilih rangka kerja yang sesuai dengan projek mereka adalah keputusan yang sangat penting. Antara bahasa semasa, PHP ialah bahasa yang sangat dinamik Beberapa rangka kerja PHP yang sangat baik seperti Yii2, Ph

Pertanyaan korelasi menyertai jadual untuk menggabungkan data daripada berbilang jadual melalui pertanyaan SQL. Dalam Golang, gunakan fungsi sql.DB.Query() untuk menentukan rentetan pertanyaan dan parameter. Jenis cantuman yang berbeza boleh digunakan, seperti INNERJOIN, LEFTJOIN, RIGHTJOIN, dan FULLOUTERJOIN, bergantung pada set hasil yang diinginkan.
