详解YII关联查询_PHP

May 28, 2016 am 11:49 AM
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次查询,而后者只有一次。两者的选择视情况而定。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

MyBatis の 1 対多のクエリ構成の詳細な説明: 関連する一般的なクエリの問題の解決 MyBatis の 1 対多のクエリ構成の詳細な説明: 関連する一般的なクエリの問題の解決 Feb 22, 2024 pm 02:18 PM

MyBatis の 1 対多のクエリ構成の詳細な説明: 一般的な関連クエリの問題を解決するには、特定のコード例が必要です。実際の開発作業では、マスター エンティティ オブジェクトとそれに関連付けられた複数のスレーブ エンティティ オブジェクトをクエリする必要がある状況によく遭遇します。 。 MyBatis では、1 対多のクエリが一般的なデータベース関連付けクエリであり、適切な設定を行うことで、関連付けられたオブジェクトのクエリ、表示、操作を簡単に実現できます。この記事では、MyBatis での 1 対多のクエリの構成方法と、関連するクエリに関する一般的な問題の解決方法を紹介します。

PHP の複数テーブル関連のクエリ スキル PHP の複数テーブル関連のクエリ スキル May 24, 2023 am 10:01 AM

PHP の複数テーブル関連クエリのスキル 関連クエリは、特に複数の関連データベース テーブルのデータを表示する必要がある場合に、データベース クエリの重要な部分です。 PHP アプリケーションでは、MySQL などのデータベースを使用するときに複数テーブル関連のクエリがよく使用されます。複数テーブルの関連付けの意味は、1 つのテーブルのデータを別のテーブルまたは複数のテーブルのデータと比較し、結果の要件を満たす行を接続することです。複数テーブルの相関クエリを実行する場合は、テーブル間の関係を考慮し、適切な相関方法を使用する必要があります。以下にいくつかのタイプを紹介します

PHP フレームワーク Yii を使用して可用性の高いクラウド バックアップ システムを開発する方法 PHP フレームワーク Yii を使用して可用性の高いクラウド バックアップ システムを開発する方法 Jun 27, 2023 am 09:04 AM

クラウド コンピューティング テクノロジの継続的な発展により、データのバックアップはすべての企業が行う必要のあるものになりました。この文脈では、可用性の高いクラウド バックアップ システムを開発することが特に重要です。 PHP フレームワーク Yii は、開発者が高性能の Web アプリケーションを迅速に構築できる強力なフレームワークです。ここでは、Yii フレームワークを使用して可用性の高いクラウド バックアップ システムを開発する方法を紹介します。データベースモデルの設計 Yii フレームワークでは、データベースモデルは非常に重要な部分です。データ バックアップ システムには多くのテーブルとリレーションシップが必要なため、

Yii2 と Phalcon: グラフィック レンダリング アプリケーションの開発にはどちらのフレームワークが適していますか? Yii2 と Phalcon: グラフィック レンダリング アプリケーションの開発にはどちらのフレームワークが適していますか? Jun 19, 2023 am 08:09 AM

現在の情報化時代では、ビッグデータ、人工知能、クラウド コンピューティング、その他のテクノロジーが大手企業の焦点となっています。その中でも、高性能なグラフィックス処理技術として、グラフィックスカードレンダリング技術がますます注目を集めています。グラフィックス カード レンダリング テクノロジは、ゲーム開発、映画やテレビの特殊効果、エンジニアリング モデリングなどの分野で広く使用されています。開発者にとって、自分のプロジェクトに合ったフレームワークを選択することは非常に重要な決定です。現在の言語の中でも PHP は非常に動的な言語であり、Yii2、Ph などの優れた PHP フレームワークもいくつかあります。

PHPでYii3フレームワークを使用するにはどうすればよいですか? PHPでYii3フレームワークを使用するにはどうすればよいですか? May 31, 2023 pm 10:42 PM

インターネットの発展に伴い、Web アプリケーション開発の需要もますます高まっています。開発者にとって、アプリケーションの開発には、開発効率を向上させる、安定性、効率性、強力なフレームワークが必要です。 Yii は、豊富な機能と優れたパフォーマンスを提供する、優れた高性能 PHP フレームワークです。 Yii3 は Yii フレームワークの次世代バージョンであり、Yii2 に基づいてパフォーマンスとコード品質をさらに最適化します。この記事では、Yii3 フレームワークを使用して PHP アプリケーションを開発する方法を紹介します。

Yii フレームワークでのデータクエリ: データに効率的にアクセスする Yii フレームワークでのデータクエリ: データに効率的にアクセスする Jun 21, 2023 am 11:22 AM

Yii フレームワークは、Web アプリケーション開発のプロセスを簡素化するための多数のツールとコンポーネントを提供するオープンソースの PHP Web アプリケーション フレームワークであり、その重要なコンポーネントの 1 つがデータ クエリです。 Yii フレームワークでは、SQL に似た構文を使用してデータベースにアクセスし、データを効率的にクエリおよび操作できます。 Yii フレームワークのクエリビルダーには主に次の種類があります: ActiveRecord クエリ、QueryBuilder クエリ、コマンド クエリ、独自の SQL クエリ

Symfony と Yii2: 大規模な Web アプリケーションの開発にはどちらのフレームワークが適していますか? Symfony と Yii2: 大規模な Web アプリケーションの開発にはどちらのフレームワークが適していますか? Jun 19, 2023 am 10:57 AM

Web アプリケーションの需要が高まるにつれ、開発者が開発フレームワークを選択する選択肢はますます増えています。 PHP フレームワークとして人気のある Symfony と Yii2 は、どちらも強力な機能とパフォーマンスを備えていますが、大規模な Web アプリケーションを開発する必要がある場合、どちらのフレームワークがより適しているのでしょうか。次に、より良い選択を行うために、Symphony と Yii2 の比較分析を行います。基本概要 Symphony は、PHP で書かれたオープンソースの Web アプリケーション フレームワークであり、上に構築されています。

Golangで結合クエリを使用してテーブルを結合するにはどうすればよいですか? Golangで結合クエリを使用してテーブルを結合するにはどうすればよいですか? Jun 05, 2024 am 11:10 AM

相関クエリはテーブルを結合し、SQL クエリを通じて複数のテーブルのデータを結合します。 Golang では、sql.DB.Query() 関数を使用してクエリ文字列とパラメータを指定します。必要な結果セットに応じて、INNERJOIN、LEFTJOIN、RIGHTJOIN、FULLOUTERJOIN などのさまざまな結合タイプを使用できます。

See all articles