ホームページ  >  記事  >  バックエンド開発  >  Yiiマルチテーブルジョイントクエリoperation_phpサンプルの詳細な説明

Yiiマルチテーブルジョイントクエリoperation_phpサンプルの詳細な説明

WBOY
WBOYオリジナル
2016-06-16 08:41:03949ブラウズ

この記事では、Yii のマルチテーブル結合クエリを要約して説明します。具体的な内容は次のとおりです。

1. 複数テーブル結合クエリの実装方法

方法は 2 つあります 1 つは、DAO を使用して SQL ステートメントを記述して を実装する方法です。ただし、SQL ステートメントが間違って書かれています。欠点も明らかであり、それらは散在しており、YII の推奨フレームワークに準拠していません。最も重要な欠点は間違いを犯しやすいことです。

もあります。1 つは、YII に付属の CActiveRecord を使用して、複数テーブルの結合クエリ

を実装する方法です。

2.全体の枠組み

ユーザーの友人関係を見つける必要があります。ユーザーの情報はユーザー テーブルに配置され、ユーザー間の関係は関係テーブルに配置され、関係の内容は関係タイプ テーブルに配置されます。明らかに、他の 2 つのテーブルをクエリするためのメイン テーブルとしてリレーショナル テーブルを使用するだけで済みます。主に実装プロセスをコードの観点から分析します。

3. CActiveRecord

まず、3 つのテーブルに対応するモデルを確立する必要があります。以下はリレーショナル テーブルのコードです。

SocialRelation.php

<&#63;php 
 
/** 
 * This is the model class for table "{{social_relation}}". 
 * 
 * The followings are the available columns in table '{{social_relation}}': 
 * @property integer $relation_id 
 * @property integer $relation_type_id 
 * @property integer $user_id 
 * @property integer $another_user_id 
 * 
 * The followings are the available model relations: 
 * @property SocialRelationType $relationType 
 * @property AccessUser $user 
 * @property AccessUser $anotherUser 
 */ 
class SocialRelation extends CActiveRecord 
{ 
  /** 
   * Returns the static model of the specified AR class. 
   * @param string $className active record class name. 
   * @return SocialRelation the static model class 
   */ 
  public static function model($className=__CLASS__) 
  { 
    return parent::model($className); 
  } 
 
  /** 
   * @return string the associated database table name 
   */ 
  public function tableName() 
  { 
    return '{{social_relation}}'; 
  } 
 
  /** 
   * @return array validation rules for model attributes. 
   */ 
  public function rules() 
  { 
    // NOTE: you should only define rules for those attributes that 
    // will receive user inputs. 
    return array( 
      array('relation_type_id, user_id, another_user_id', 'numerical', 'integerOnly'=>true), 
      // The following rule is used by search(). 
      // Please remove those attributes that should not be searched. 
      array('relation_id, relation_type_id, user_id, another_user_id', 'safe', 'on'=>'search'), 
    ); 
  } 
 
  /** 
   * @return array relational rules. 
   */ 
  public function relations() 
  { 
    // NOTE: you may need to adjust the relation name and the related 
    // class name for the relations automatically generated below. 
    return array( 
      'relationType' => array(self::BELONGS_TO, 'SocialRelationType', 'relation_type_id'), 
      'user' => array(self::BELONGS_TO, 'AccessUser', 'user_id'), 
      'anotherUser' => array(self::BELONGS_TO, 'AccessUser', 'another_user_id'), 
    ); 
  } 
 
  /** 
   * @return array customized attribute labels (name=>label) 
   */ 
  public function attributeLabels() 
  { 
    return array( 
      'relation_id' => 'Relation', 
      'relation_type_id' => 'Relation Type', 
      'relation_type_name' => 'Relation Name', 
      'user_id' => 'User ID', 
      'user_name' => 'User Name', 
      'another_user_id' => 'Another User', 
      'another_user_name' => 'Another User Name', 
    ); 
  } 
 
  /** 
   * Retrieves a list of models based on the current search/filter conditions. 
   * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions. 
   */ 
  public function search() 
  { 
    // Warning: Please modify the following code to remove attributes that 
    // should not be searched. 
 
    $criteria=new CDbCriteria; 
 
    $criteria->compare('relation_id',$this->relation_id); 
    $criteria->compare('relation_type_id',$this->relation_type_id); 
    $criteria->compare('user_id',$this->user_id); 
    $criteria->compare('another_user_id',$this->another_user_id); 
    $criteria->with=array( 
      'relationType', 
    ); 
 
    return new CActiveDataProvider($this, array( 
      'criteria'=>$criteria, 
    )); 
  } 
} 

説明の便宜上、主テーブルはテーブル A (クエリが実行されるテーブル)、参照テーブルはテーブル B (外部キーによって参照されるテーブル) であることに同意します
Gii を使用してモデルを自動的に生成することをお勧めします。これにより、テストの便宜上、追加、削除、変更、およびクエリ ページであるメイン テーブルに対して CRUD を生成できます。テーブルの場合は、モデルを生成するだけです。
1. このモデルとデータベーステーブルの基本情報を取得するには、モデル関数 と tablename 関数を使用します。変更せずに自動生成

2. ルール関数 。この関数は主にパラメーターの検証方法を指定するために使用されます。一部のパラメーターは検証を必要としない場合でも、ルールに含める必要があることに注意してください。そうしないと、モデルはパラメータを取得できなくなります

3. 関係関数 、この関数は非常に重要であり、テーブル間の関係を定義するために使用されます。その意味については、以下で詳しく説明します。

'relationType' => array(self::BELONGS_TO, 'SocialRelationType', 'relation_type_id')
このコードの構造は次のとおりです
'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...追加オプション)
VarName はリレーションシップの名前です。今後、この名前を使用して外部キー参照テーブルのフィールドにアクセスします。

RelationType は関係のタイプであり、設定が間違っている場合、Yii は合計 4 種類の関係を提供します。

BELONGS_TO (所属): テーブル A と B の関係が 1 対多の場合、テーブル B はテーブル A に属します
HAS_MANY (複数あり): テーブル A と B の関係が 1 対多の場合、A には複数の B があります
HAS_ONE (1 つあります): これは HAS_MANY の特殊なケースであり、A には B
が最大 1 つあります。 MANY_MANY: これはデータベース内の多対多の関係に対応します
ClassName は参照テーブル名であり、外部キーによって参照されるテーブルの名前であり、テーブル B

の名前です。

ForeignKey は外部キーの名前です。ここで主に入力するのは、メイン テーブルの外部キーの名前です。これは、テーブル A の外部キーのテーブル名です。間違った名前

テーブル B に二重の主キーがある場合、次の方法で実装できます。このアプローチは、各テーブルに独立した意味のない主キーを使用することが最善であり、そうしないとさまざまな問題が発生します。発生しやすく管理が不便になります

'categories'=>array(self::MANY_MANY, 'Category', 
        'tbl_post_category(post_id, category_id)'), 

追加オプション 追加オプション、ほとんど使用されません
4 つのattributeLabels 関数 、これはテーブル属性の表示名で、powerdesigner のコードと名前の関係に少し似ています。最初の部分はデータベース フィールド名で、後者はデータベース フィールド名です。部分は表示名です
5 検索関数 は、テーブル クエリの結果を生成するために使用される関数です。ここでは、具体的な使用方法については説明しません。 API 。 Gii を使用して生成された場合、変更は必要ありません。

同様に、残りの 2 つの参照テーブルを生成します

関係タイプ テーブル: SocialRelationType.php

<&#63;php 
 
/** 
 * This is the model class for table "{{social_relation_type}}". 
 * 
 * The followings are the available columns in table '{{social_relation_type}}': 
 * @property integer $relation_type_id 
 * @property string $relation_type_name 
 * 
 * The followings are the available model relations: 
 * @property SocialRelation[] $socialRelations 
 */ 
class SocialRelationType extends CActiveRecord 
{ 
  /** 
   * Returns the static model of the specified AR class. 
   * @param string $className active record class name. 
   * @return SocialRelationType the static model class 
   */ 
  public static function model($className=__CLASS__) 
  { 
    return parent::model($className); 
  } 
 
  /** 
   * @return string the associated database table name 
   */ 
  public function tableName() 
  { 
    return '{{social_relation_type}}'; 
  } 
 
  /** 
   * @return array validation rules for model attributes. 
   */ 
  public function rules() 
  { 
    // NOTE: you should only define rules for those attributes that 
    // will receive user inputs. 
    return array( 
      array('relation_type_name', 'length', 'max'=>10), 
      // The following rule is used by search(). 
      // Please remove those attributes that should not be searched. 
      array('relation_type_id, relation_type_name', 'safe', 'on'=>'search'), 
    ); 
  } 
 
  /** 
   * @return array relational rules. 
   */ 
  public function relations() 
  { 
    // NOTE: you may need to adjust the relation name and the related 
    // class name for the relations automatically generated below. 
    return array( 
      'socialRelations' => array(self::HAS_MANY, 'SocialRelation', 'relation_type_id'), 
    ); 
  } 
 
  /** 
   * @return array customized attribute labels (name=>label) 
   */ 
  public function attributeLabels() 
  { 
    return array( 
      'relation_type_id' => 'Relation Type', 
      'relation_type_name' => 'Relation Type Name', 
    ); 
  } 
 
  /** 
   * Retrieves a list of models based on the current search/filter conditions. 
   * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions. 
   */ 
  public function search() 
  { 
    // Warning: Please modify the following code to remove attributes that 
    // should not be searched. 
 
    $criteria=new CDbCriteria; 
 
    $criteria->compare('relation_type_id',$this->relation_type_id); 
    $criteria->compare('relation_type_name',$this->relation_type_name,true); 
 
    return new CActiveDataProvider($this, array( 
      'criteria'=>$criteria, 
    )); 
  } 
} 

ユーザーテーブル: AccessUser.php

<&#63;php 
 
/** 
 * This is the model class for table "{{access_user}}". 
 * 
 * The followings are the available columns in table '{{access_user}}': 
 * @property integer $id 
 * @property string $name 
 * @property string $password 
 * @property string $lastlogin 
 * @property string $salt 
 * @property string $email 
 * @property integer $status 
 * 
 * The followings are the available model relations: 
 * @property SocialRelation[] $socialRelations 
 * @property SocialRelation[] $socialRelations1 
 */ 
class AccessUser extends CActiveRecord 
{ 
  /** 
   * Returns the static model of the specified AR class. 
   * @param string $className active record class name. 
   * @return AccessUser the static model class 
   */ 
  public static function model($className=__CLASS__) 
  { 
    return parent::model($className); 
  } 
 
  /** 
   * @return string the associated database table name 
   */ 
  public function tableName() 
  { 
    return '{{access_user}}'; 
  } 
 
  /** 
   * @return array validation rules for model attributes. 
   */ 
  public function rules() 
  { 
    // NOTE: you should only define rules for those attributes that 
    // will receive user inputs. 
    return array( 
      array('status', 'numerical', 'integerOnly'=>true), 
      array('name, password, salt, email', 'length', 'max'=>255), 
      array('lastlogin', 'safe'), 
      // The following rule is used by search(). 
      // Please remove those attributes that should not be searched. 
      array('id, name, password, lastlogin, salt, email, status', 'safe', 'on'=>'search'), 
    ); 
  } 
 
  /** 
   * @return array relational rules. 
   */ 
  public function relations() 
  { 
    // NOTE: you may need to adjust the relation name and the related 
    // class name for the relations automatically generated below. 
    return array( 
      'user_name' => array(self::HAS_MANY, 'SocialRelation', 'user_id'), 
      'anotherUser_name' => array(self::HAS_MANY, 'SocialRelation', 'another_user_id'), 
    ); 
  } 
 
  /** 
   * @return array customized attribute labels (name=>label) 
   */ 
  public function attributeLabels() 
  { 
    return array( 
      'id' => 'ID', 
      'name' => 'Name', 
      'password' => 'Password', 
      'lastlogin' => 'Lastlogin', 
      'salt' => 'Salt', 
      'email' => 'Email', 
      'status' => 'Status', 
    ); 
  } 
 
  /** 
   * Retrieves a list of models based on the current search/filter conditions. 
   * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions. 
   */ 
  public function search() 
  { 
    // Warning: Please modify the following code to remove attributes that 
    // should not be searched. 
 
    $criteria=new CDbCriteria; 
 
    $criteria->compare('id',$this->id); 
    $criteria->compare('name',$this->name,true); 
    $criteria->compare('password',$this->password,true); 
    $criteria->compare('lastlogin',$this->lastlogin,true); 
    $criteria->compare('salt',$this->salt,true); 
    $criteria->compare('email',$this->email,true); 
    $criteria->compare('status',$this->status); 
 
    return new CActiveDataProvider($this, array( 
      'criteria'=>$criteria, 
    )); 
  } 
} 

4. コントローラー
3 つのテーブルを導入した後、同様に、Gii を使用してメイン テーブル (テーブル A) の CRUD を生成し、コードにいくつかの変更を加えるだけです。以下の通り

SocialRelationController.php

<&#63;php 
 
class SocialRelationController extends Controller 
{ 
  /** 
   * @var string the default layout for the views. Defaults to '//layouts/column2', meaning 
   * using two-column layout. See 'protected/views/layouts/column2.php'. 
   */ 
  public $layout='//layouts/column2'; 
 
  /** 
   * @return array action filters 
   */ 
  public function filters() 
  { 
    return array( 
      'accessControl', // perform access control for CRUD operations 
      'postOnly + delete', // we only allow deletion via POST request 
    ); 
  } 
 
  /** 
   * Specifies the access control rules. 
   * This method is used by the 'accessControl' filter. 
   * @return array access control rules 
   */ 
  public function accessRules() 
  { 
    return array( 
      array('allow', // allow all users to perform 'index' and 'view' actions 
        'actions'=>array('index','view'), 
        'users'=>array('*'), 
      ), 
      array('allow', // allow authenticated user to perform 'create' and 'update' actions 
        'actions'=>array('create','update'), 
        'users'=>array('@'), 
      ), 
      array('allow', // allow admin user to perform 'admin' and 'delete' actions 
        'actions'=>array('admin','delete'), 
        'users'=>array('admin'), 
      ), 
      array('deny', // deny all users 
        'users'=>array('*'), 
      ), 
    ); 
  } 
 
  /** 
   * Displays a particular model. 
   * @param integer $id the ID of the model to be displayed 
   */ 
  public function actionView($id) 
  { 
    $this->render('view',array( 
      'model'=>$this->loadModel($id), 
    )); 
  } 
 
  /** 
   * Creates a new model. 
   * If creation is successful, the browser will be redirected to the 'view' page. 
   */ 
  public function actionCreate() 
  { 
    $model=new SocialRelation; 
 
    // Uncomment the following line if AJAX validation is needed 
    // $this->performAjaxValidation($model); 
 
    if(isset($_POST['SocialRelation'])) 
    { 
      $model->attributes=$_POST['SocialRelation']; 
      if($model->save()) 
        $this->redirect(array('view','id'=>$model->relation_id)); 
    } 
 
    $this->render('create',array( 
      'model'=>$model, 
    )); 
  } 
 
  /** 
   * Updates a particular model. 
   * If update is successful, the browser will be redirected to the 'view' page. 
   * @param integer $id the ID of the model to be updated 
   */ 
  public function actionUpdate($id) 
  { 
    $model=$this->loadModel($id); 
 
    // Uncomment the following line if AJAX validation is needed 
    // $this->performAjaxValidation($model); 
 
    if(isset($_POST['SocialRelation'])) 
    { 
      $model->attributes=$_POST['SocialRelation']; 
      if($model->save()) 
        $this->redirect(array('view','id'=>$model->relation_id)); 
    } 
 
    $this->render('update',array( 
      'model'=>$model, 
    )); 
  } 
 
  /** 
   * Deletes a particular model. 
   * If deletion is successful, the browser will be redirected to the 'admin' page. 
   * @param integer $id the ID of the model to be deleted 
   */ 
  public function actionDelete($id) 
  { 
    $this->loadModel($id)->delete(); 
 
    // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser 
    if(!isset($_GET['ajax'])) 
      $this->redirect(isset($_POST['returnUrl']) &#63; $_POST['returnUrl'] : array('admin')); 
  } 
 
  /** 
   * Lists all models. 
   */ 
  public function actionIndex() 
  { 
    if(Yii::app()->user->id != null){ 
      $dataProvider=new CActiveDataProvider( 
        'SocialRelation',  
        array('criteria'=>array('condition'=>'user_id='.Yii::app()->user->id, 
      )) 
      ); 
      $this->render('index',array( 
        'dataProvider'=>$dataProvider, 
      )); 
    } 
     
  } 
 
  /** 
   * Manages all models. 
   */ 
  public function actionAdmin() 
  { 
    $model=new SocialRelation('search'); 
    $model->unsetAttributes(); // clear any default values 
    if(isset($_GET['SocialRelation'])) 
      $model->attributes=$_GET['SocialRelation']; 
 
    $this->render('admin',array( 
      'model'=>$model, 
    )); 
  } 
 
  /** 
   * Returns the data model based on the primary key given in the GET variable. 
   * If the data model is not found, an HTTP exception will be raised. 
   * @param integer $id the ID of the model to be loaded 
   * @return SocialRelation the loaded model 
   * @throws CHttpException 
   */ 
  public function loadModel($id) 
  { 
    $model=SocialRelation::model()->findByPk($id); 
    if($model===null) 
      throw new CHttpException(404,'The requested page does not exist.'); 
    return $model; 
  } 
 
  /** 
   * Performs the AJAX validation. 
   * @param SocialRelation $model the model to be validated 
   */ 
  protected function performAjaxValidation($model) 
  { 
    if(isset($_POST['ajax']) && $_POST['ajax']==='social-relation-form') 
    { 
      echo CActiveForm::validate($model); 
      Yii::app()->end(); 
    } 
  } 
} 

各関数と変数の簡単な紹介
$layout はレイアウト ファイルの場所です。レイアウト ファイルの使用方法についてはここでは説明しません

フィルターはフィルターを定義します、ここは水が深いです

accessRules アクセス メソッドは、これらのユーザーがこのモジュールにアクセスできることを意味します

array('allow', // allow all users to perform 'index' and 'view' actions 
        'actions'=>array('index','view'), 
        'users'=>array('*'), 
      ), 

allow 表示允许访问的规则如下,deny表示拒绝访问的规则如下。
action表示规定规则使用的动作

user表示规则适用的用户群组,*表示所有用户,@表示登录后的用户,admin表示管理员用户

actionXXX 各个action函数

这里值得注意的是 这个函数

public function actionIndex() 
  { 
    if(Yii::app()->user->id != null){ 
      $dataProvider=new CActiveDataProvider( 
        'SocialRelation',  
        array('criteria'=>array('condition'=>'user_id='.Yii::app()->user->id, 
      )) 
      ); 
      $this->render('index',array( 
        'dataProvider'=>$dataProvider, 
      )); 
    } 
     
  } 

其中我们可以在dataProvider中设置相应的查询条件,注意这里设置是对于主表(A表)进行的,用的字段名也是主表中的,因为我们要显示的是当前用户的好友,于是,这里我们使用Yii::app()->user->id取得当前用户的id 。

loadModel 用于装载模型,这里我们可以看到findByPk查询了数据库。

performAjaxValidation 用于Ajax验证。

5、视图View

index.php

<&#63;php 
/* @var $this SocialRelationController */ 
/* @var $dataProvider CActiveDataProvider */ 
 
$this->breadcrumbs=array( 
  'Social Relations', 
); 
&#63;> 
 
<h1>Social Relations</h1> 
 
<&#63;php $this->widget('zii.widgets.CListView', array( 
  'dataProvider'=>$dataProvider, 
  'itemView'=>'_view', 
)); &#63;> 

我们使用一个 CListView控件进行显示,其中itemView为内容显示的具体表单,dataProvider这个是内容源,我们在controller中已经设定了。

_view.php

<&#63;php 
/* @var $this SocialRelationController */ 
/* @var $data SocialRelation */ 
&#63;> 
 
<div class="view"> 
 
  <b><&#63;php echo CHtml::encode($data->getAttributeLabel('relation_id')); &#63;>:</b> 
  <&#63;php echo CHtml::link(CHtml::encode($data->relation_id), array('view', 'id'=>$data->relation_id)); &#63;> 
  <br /> 
 
  <b><&#63;php echo CHtml::encode($data->getAttributeLabel('relation_type_id')); &#63;>:</b> 
  <&#63;php echo CHtml::encode($data->relation_type_id); &#63;> 
  <br /> 
 
  <b><&#63;php echo CHtml::encode($data->getAttributeLabel('relation_type_name')); &#63;>:</b> 
  <&#63;php  
    echo $data->relationType->relation_type_name; 
  &#63;> 
  <br /> 
   
  <b><&#63;php echo CHtml::encode($data->getAttributeLabel('user_id')); &#63;>:</b> 
  <&#63;php echo CHtml::encode($data->user_id); &#63;> 
  <br /> 
 
  <b><&#63;php echo CHtml::encode($data->getAttributeLabel('user_name')); &#63;>:</b> 
  <&#63;php  
    echo $data->user->name; 
  &#63;> 
  <br /> 
 
  <b><&#63;php echo CHtml::encode($data->getAttributeLabel('another_user_id')); &#63;>:</b> 
  <&#63;php echo CHtml::encode($data->another_user_id); &#63;> 
  <br /> 
 
  <b><&#63;php echo CHtml::encode($data->getAttributeLabel('another_user_name')); &#63;>:</b> 
  <&#63;php 
    echo $data->anotherUser->name; 
  &#63;> 
  <br /> 
   
</div> 

主要都是类似的,我们看其中的一条

复制代码 代码如下:
a4b561c25d9afb9ac8dc4d70affff4194ffa136db924f78215eb2994916c495fgetAttributeLabel('relation_type_name')); ?>:0d36329ec37a2cc24d42c7229b69747a 
bdf53b1d89582f9578e1b6c0fbc1b9e9relationType->relation_type_name; ?>
 
第一行为显示标签,在模型中我们设定的显示名就在这里体现出来
第二行为内容显示,这里的relationType是在模型中设置的关系名字,后面的relation_type_name是引用表的字段名(B表中的名字)

6、总结

通过上面的步骤,我们就实现了整个联合查询功能,效果图如下所示:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

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