Yii的关联查询

在项目过程中许多地方需要用到关联查询的,join左连接 (left join),又称内连接 (inner join),要两个表格内都有同样的值,那一条记录才会被选出,说白了是要表里面有重复的字段。

这种情况下把两个表关联起来查询出我们需要的内容。在项目中每个model写有基于model的service文件,基本封装了增删改查统计等常用操作。但是没有涉及到关联查询的。也不想每次都写sql语句来执行。会看起来很乱。查了很多网上的资料关于Yii框架的数据库操作。

基础内容如下:

(我用的是Yii1.1.4,还是Yii1.1的方法 注:HAS_MANY HAS_ONE是yii1.1.7版本才更新的)

虽然框架注释和文档有中文翻译,不过看了感觉还是不明不白的,再通过翻译和自己的理解总结一下。


CDbCriteria类中定义的变量:

const
PARAM_PREFIX=':ycp'; //参数前缀 public static $paramCount=0; //匿名参数生成名称的计数器 public $select='*'; //select 列名用逗号分隔或数组形式 默认查所有 public $distinct=false; //true取唯一值 默认false public $condition=''; //相当于where条件 public $params=array(); //用占位符当索引的参数数组 public $limit=-1; //返回记录条数,默认-1无限制 public $offset=-1; //偏移量,默认从0开始 public $order=''; //排序,相当于order by public $group=''; //分组,相当于group by public $join=''; //LEFT JOIN users ON users.id=authorID public $having=''; //添加group by的条件 public $with; //关系查询条件 用于AR方法传递参数 public $alias; //表别名 不设置默认为‘t’ public $together; //boolean型,用于AR中HAS_MANY和MANY_MANY关系中。设置为true只执行单个sql,设置为false时 执行HAS_MANY public $index; //结果集属性索引,默认null从0开始 public $scopes; //应用范围,用法好复杂

查询合集——AR中的方法:

1.findAll该方法是根据一个条件查询一个集合  condition是查询条件,params是sql查询参数
public function findAll($condition='',$params=array())  
$admin=Admin::model()->findAll($condition,$params); 
$admin=Admin::model()->findAll("username=:name",array(":name"=>$username)); 
$admin=Admin::model()->findAll(“username=:name and age=:age” , array(“:name”=>$name, “age”=>$age)); 
$admin=Admin::model()->findAll(“username like :name and age=:age” , array(“:name”=>$name, “age”=>$age)); 
$infoArr= NewsList::model()->findAll("status = '1' ORDER BY id DESC limit 10 ");

2.findAllByPk(该方法是根据主键查询一个集合,可以使用多个主键)
public function findAllByPk($pk,$condition='',$params=array())
$admin=Admin::model()->findAllByPk($postIDs,$condition,$params); 
$admin=Admin::model()->findAllByPk($id,"name like :name and age=:age",array(':name'=>$name,'age'=>$age)); 
$admin=Admin::model()->findAllByPk(array(1,2));

3.findAllByAttributes (该方法是根据条件查询一个集合,可以是多个条件,把条件放到数组里面)
public function findAllByAttributes($attributes,$condition='',$params=array())
$admin=Admin::model()->findAllByAttributes($attributes,$condition,$params); 
$admin=Admin::model()->findAllByAttributes(array('username'=>'admin'));

4.findAllBySql (该方法是根据SQL语句查询一个数组)
public function findAllBySql($sql,$params=array())
$admin=Admin::model()->findAllBySql($sql,$params); 
$admin=Admin::model()->findAllBySql("select * from admin where username like :name",array(':name'=>''));

5.根据主键查询出一个对象,如:findByPk(1);
public function findByPk($pk,$condition='',$params=array())
$admin=Admin::model()->findByPk($postID,$condition,$params); 
$admin=Admin::model()->findByPk(1);

6.根据一个条件查询出一组数据,可能是多个,但是他只返回第一行数据
public function find($condition='',$params=array())
$row=Admin::model()->find($condition,$params); 
$row=Admin::model()->find('username=:name',array(':name'=>'admin'));

7.根据条件查询一组数据,可以是多个条件,把条件放到数组里面,查询的也是第一条数据
public function findByAttributes($attributes,$condition='',$params=array())
$admin=Admin::model()->findByAttributes($attributes,$condition,$params); 
$admin=Admin::model()->findByAttributes(array('username'=>'admin'));

8.根据SQL语句查询一组数据,他查询的也是第一条数据
public function findBySql($sql,$params=array())
$admin=Admin::model()->findBySql($sql,$params); 
$admin=Admin::model()->findBySql("select * from admin where username=:name",array(':name'=>'admin'));

9.根据一个条件查询一个集合有多少条记录,返回一个int型数字
public function count($condition='',$params=array())
$n=Post::model()->count($condition,$params); 
$n=Post::model()->count("username=:name",array(":name"=>$username));

10.根据SQL语句查询一个集合有多少条记录,返回一个int型数字
public function countBySql($sql,$params=array())
$n=Post::model()->countBySql($sql,$params); 
$n=Post::model()->countBySql("select * from admin where username=:name",array(':name'=>'admin'));

11.根据一个条件查询查询得到的数组有没有数据,如果有数据返回一个true,否则没有找到
public function exists($condition='',$params=array())
$exists=Post::model()->exists($condition,$params); 
$exists=Post::model()->exists("name=:name",array(":name"=>$username));

查询合集——CDbCriteria中的方法:

1.拼一个获得SQL的方法,在根据find查询出一个对象
$criteria=new CDbCriteria; 
$criteria->select='username'; 
$criteria->condition='username=:username'; //请注意,这是一个查询的条件,且只有一个查询条件.多条件用addCondition 
$criteria->params=array(":username=>'admin'"); 
$criteria->order ="id DESC"; 
$criteria->limit ="3"; 
$post=Post::model()->find($criteria);

2.多条件查询的语句new CDbCriteria
$criteria=new CDbCriteria;
public function addCondition($condition,$operator='AND') $criteria->addCondition("id=1"); //查询条件,即where id = 1 $criteria->addCondition('id=1','OR'); //这是OR条件,多个条件的时候,该条件是OR而非AND public function addInCondition($column,$values,$operator='AND') $criteria->addInCondition('id',array(1,2,3,4,5)); //代表where id IN (1,2,3,4,5,); public function addNotInCondition($column,$values,$operator='AND') $criteria->addNotInCondition('id',array(1,2,3,4,5)); //与上面正好相法,是NOT IN public function addSearchCondition($column,$keyword,$escape=true,$operator='AND',$like='LIKE') $criteria->addSearchCondition('name','分类'); //搜索条件,其实代表了where name like '%分类%' public function addBetweenCondition($column,$valueStart,$valueEnd,$operator='AND') $criteria->addBetweenCondition('id', 1, 4);//between 1 and 4 public function compare($column, $value, $partialMatch=false, $operator='AND', $escape=true) $criteria->compare('id', 1); //这个方法比较特殊,他会根据你的参数自动处理成addCondition或者addInCondition. $criteria->compare('id',array(1,2,3)); //即如果第二个参数是数组就会调用addInCondition $criteria->select ='id,parentid,name'; //代表了要查询的字段,默认select='*'; $criteria->join ='xxx'; //连接表 $criteria->with ='xxx'; //调用relations $criteria->limit = 10; //取10条数据,如果小于0,则不作处理 $criteria->offset = 1; //两条合并起来,则表示 limit 10 offset 1,或者代表了。limit 1,10 $criteria->order ='xxx DESC,XXX ASC';//排序条件 $criteria->group ='group 条件'; $criteria->having ='having 条件 '; $criteria->distinct = FALSE;//是否唯一查询 $re = Admin::model()->findAll($criteria); 注意当调用addCondition方法时是给查询追加条件,默认用AND连接条件,参数condition条件也可是数组,数组中所有元素即为追加条件,通过操作符连接。

下面就是说使用join的时候 连接表,然后用with调用relations方法

$criteria->join = 'left join table2 t2 on(t.id=t2.tid)'; //连接表
$criteria->with = 'xxx'; //调用relations

什么是relations?

在继承了AR的model类中有一个relations方法,刚开始是空的,我们要建立关联关系就需要在这个方法中写入,目的是为了

在执行关联查询之前,需要让AR知道一个AR类是怎么关联到另一个的,Model类之间要建立联系,两个类之间的关联关系等同于相对应的数据表之间的关系,两个表之间的关系有一对一、一对多,多对多三种。对应于AR类之间也是这样的关系:

const BELONGS_TO='CBelongsToRelation';
const HAS_ONE='CHasOneRelation'; const HAS_MANY='CHasManyRelation'; const MANY_MANY='CManyManyRelation'; const STAT='CStatRelation';  
AR里定义了这些常量

1、一对一(one-to-one)

  HAS_ONE(有一个): 这是 HAS_MANY 的一个特例,A 最多有一个 B (例如 User 最多有一个 Profile);

2、一对多(one-to-many)

  BELONGS_TO(属于): 如果表 A 和 B 之间的关系是一对多,则 表 B 属于 表 A (例如 Post 属于 User);

  HAS_MANY(有多个): 如果表 A 和 B 之间的关系是一对多,则 A 有多个 B (例如 User 有多个 Post);

3、多对多(many-to-many)

  MANY_MANY: 这个对应于数据库中的 多对多 关系。

  由于多数 DBMS 不直接支持 多对多 关系,因此需要有一个关联表(一张表包含另外两张表的主键id)将 多对多 关系分割为 一对多 关系。

 在model中覆盖CActiveRecord中的relations()方法。

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(
        );
    }
此方法返回一个关系配置数组,写在return array()中
'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 指定关系中使用的外键(一个或多个)。'foreignKey'=>'';
additional options 可以是别名 'alias'=>'';

多对多关系中
比如说品牌Brand和分类Category
在BrandModel中
‘Categorys’=>array(self::Many_Many,'CategoryModel','brand_category(brand_id,category_id)),
在CategoryModel中
‘brands’=>array(self::Many_Many,'BrandModel','brand_category(category_id,brand_id)),

(只需要设置一方即可)

这样就可以在Brand的Views里面通过Categorys来访问CategoryModel的属性值
STAT静态查询 仅用于HAS_MANY和MANY_MANY

 

posted @ 2018-12-28 15:59  中国骑士  阅读(477)  评论(0编辑  收藏  举报
jQuery火箭图标返回顶部代码