放牧代码和思想
专注自然语言处理、机器学习算法
    This thing called love. Know I would've. Thrown it all away. Wouldn't hesitate.

Yii里使用CSqlDataProvider进行更为灵活的查询

在CGridView里,可以用CSqlDataProvider代替CActiveDataProvider来进行更加复杂的查询。CActiveDataProvider使用的是面向对象的思想,如果你想join一张表,你得做两件事情:

  1. 给这张表生成一个模型,比如说叫它UserGroupAssignment

  2. 在model的relation里定义外键关联的属性,比如说Users,关系是MANY_MANY

  3. 定义一个CDbCriteria,用with来eager load这个属性Users

然后就可以查询了,但是问题在于tbl_UserGroupAssignment这张表可不单单是用来做多对多的关联用的,这张表有三个字段,分别是uid,gid,role。也就是说,还有一个很重要的字段是role,但是relation定义出来的属性Users属于user表,里面是没有role字段的,于是问题就来了。比如说我想查询群组gid = 1里所有role为member的用户,怎么办?role属性不存在于任何一个对象中!麻烦就大了!

这时候传统的sql语句就可以排上用场了,使用CSqlDataProvider可以灵活地处理这个问题,我只举一个简单的例子,并没有涉及上面的join,你可以自己发挥。

controller:

		$count = Yii::app()->db->createCommand('SELECT COUNT(*) FROM tbl_user')->queryScalar();
		$sql = 'SELECT * FROM tlb_user';
		$dataProvider = new CSqlDataProvider($sql, array(
				'totalItemCount' => $count,
				'sort' => array(
						'attributes' => array(
								'name',
						) 
				),
				'pagination' => array(
						'pageSize' => 10 
				) 
		));
		$this->render('addExperts',array(
			'dataProvider'=>$dataProvider,
		));

view:

<?php 
    $this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'menu-grid',
    'dataProvider'=>$dataProvider,
    'columns'=>array(
        array(
            'id'=>'autoId',
            'class'=>'CCheckBoxColumn',
            'selectableRows' => '50',   
        ),
        'name',
    ),
)); ?>

效果:

SQLdataprovider不方便的地方在于,需要写一句一共多少条记录,查出来的记录是纯数组而不是AR类型数组,所以在显示的时候很麻烦,无法用到AR类中的辅助显示的成员函数。比如查出来一个字段是0或1,你不能直接显示给用户看,至少要变成是和否,这一下变换一般是在AR类中完成的,可是数组又用不了。这还是最简单的情况,一些复杂的显示可能要另开炉灶复制粘贴一大段代码,造成代码维护艰难和难以阅读。

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » Yii里使用CSqlDataProvider进行更为灵活的查询

评论 欢迎留言

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

我的作品

HanLP自然语言处理包《自然语言处理入门》