YiiのCSqlDataProviderを利用する際のポイント

Yiiでは単一のテーブルを利用する場合だとか、ちょっとしたJoinで済むような場合は、CActiveDataProviderを使うのが簡単でよいんですが、relationsでは書けないようなSQLを発行したい場合は、CActiveDataProviderのかわりにCSqlDataProviderを利用することができます。

今回は、CSqlDataProviderを利用する際のポイントを幾つかまとめておきます。

CDbCriteriaを利用しつつ、CSqlDataProviderで発行するSQLを作成する。

$criteria=new CDbCriteria;
$criteria->compare('t.id',$this->id);
$criteria->compare('money',$this->money);
$criteria->compare('m.name_sei_kana',$this->melmaneSei,true);
$criteria->compare('m.name_mei_kana',$this->melmaneMei,true);
$criteria->compare('m.email',$this->melmaneEmail,true);

のようなCDbCriteriaで作成した検索条件を利用する場合は、

$where=$criteria->condition;
$params=$criteria->params;
unset($criteria);

$sql = Yii::app()->db->createCommand()
  ->select('t.*,m.*')
  ->from('tbl_payhist t')
  ->leftjoin('tbl_melmane m', 't.user_id=m.user_id')
  ->where($where, $params)
  ->text;

のようにするとSQLを作成できます。CSqlDataProviderで利用する場合は

return new CSqlDataProvider($sql,array(
  'params'=>$params,
));

のようにします。

CSqlDataProviderでページネーションを利用する。

CSqlDataProviderでページネーションを利用するには、以下のようにtotalItemCountに値を渡す必要があります。

$count=Yii::app()->db->createCommand('select count(*) from tbl_payhist')->queryScalar();
return new CSqlDataProvider($sql,array(
  'params'=>$params,
  'totalItemCount'=>$count,
));

ページネーションの細かい指定をする場合は

$count=Yii::app()->db->createCommand('select count(*) from tbl_payhist')->queryScalar();
return new CSqlDataProvider($sql,array(
  'params'=>$params,
  'totalItemCount'=>$count,
  'pagination'=>array(
    'pageSize'=>10,
  ),
));

のようにします。

CSqlDataProviderでソートを利用する。

CSqlDataProviderでソートを利用するには、

$count=Yii::app()->db->createCommand('select count(*) from tbl_payhist')->queryScalar();
return new CSqlDataProvider($sql,array(
  'params'=>$params,
  'totalItemCount'=>$count,
  'pagination'=>array(
    'pageSize'=>10,
  ),
  'sort'=>$sort,
));

のように、sortの設定をします。なお$sortの部分は以下のような感じになります。
この部分で設定がないとフィールドがソート可能になりませんので注意が必要です。

$sort= new CSort();
$sort->multiSort = true;
$sort->attributes = array(
  'id' => array(
      'asc'=>'t.id',
      'desc'=>'t.id DESC',
      'default'=>'desc',
  ),
  'money' => array(
      'asc'=>'money',
      'desc'=>'money DESC',
      'default'=>'desc',
  ),
  'melmaneSei' => array(
      'asc'=>'m.name_sei_kana, m.name_mei_kana',
      'desc'=>'m.name_sei_kana DESC, m.name_mei_kana DESC',
      'default'=>'desc',
  ),
  'melmaneMei' => array(
      'asc'=>'m.name_mei_kana',
      'desc'=>'m.name_mei_kana DESC',
      'default'=>'desc',
  ),
  'melmaneEmail' => array(
      'asc'=>'m.email',
      'desc'=>'m.email DESC',
      'default'=>'desc',
  ),
);
$sort->defaultOrder = 't.id DESC';

ビューでの表示について。

ビューで表示する場合は、以下のような感じに書きます。

<?php $this->widget('bootstrap.widgets.TbGridView',array(
  'id'=>'payhist-grid',
  'dataProvider'=>$model->sqlprovider(),
  'filter'=>$model,
  'ajaxUpdate'=>true,
  'columns'=>array(
    array(
      'header'=>'姓',
      'name'=>'melmaneSei',
      'value'=>'$data["name_sei_kana"]',
    ),
    array(
      'header'=>'名',
      'name'=>'melmaneMei',
      'value'=>'$data["name_mei_kana"]',
    ),
    array(
      'header'=>'メルアド',
      'name'=>'melmaneEmail',
      'value'=>'$data["email"]',
    ),
    array(
      'header'=>'支払い金',
      'name'=>'money',
      'value'=>'$data["money"]',
    ),
  ),
)); ?>

CActiveDataProviderでは、

'value'=>'$data->name_sei_kana',

のように書きましたが、CSqlDataProviderでは、

'value'=>'$data["name_sei_kana"]',

のように書く必要があります。

なお、headerで値を指定すると、この値がテーブルのカラムで表示されるようになります。

 

※参考
CSqlDataProviderについて。
CDataColumnのsortableについて。
Csortについて。
CDbCommandについて。

投稿日:
カテゴリー: php タグ: