Yii - AR

来源:互联网 发布:rpc框架 java c 编辑:程序博客网 时间:2024/04/29 15:08

http://www.yiiframework.com/doc/guide/1.1/en/database.ar


you should overrideCActiveRecord::getDbConnection(). TheCActiveRecord class is the baseclass for all AR classes.


Tip: There are two ways to work with multiple databases in AR. If the schemas of the databases are different, you may create different base AR classes with different implementation ofgetDbConnection(). Otherwise, dynamically changing the static variable CActiveRecord::db is a better idea.



define an AR class byextending CActiveRecord.


class Post extends CActiveRecord{    public static function model($className=__CLASS__)    {        return parent::model($className);    }     public function tableName()    {        return 'tbl_post';    }}


if all our AR class files are under protected/models, we can configure the application as follows:

return array(  'import'=>array(      'application.models.*',  ),);


To use the table prefix feature, the tableName() method for an AR class may be overridden as follows,

public function tableName(){    return '{{post}}';}

Although we never explicitly declare the title property in the Postclass, we can still access it in the above code. This is because title isa column in the tbl_post table, and CActiveRecord makes it accessible as aproperty with the help of the PHP__get() magic method. An exception willbe thrown if we attempt to access a non-existing column in the same way.


AR relies on well defined primary keys of tables. If a table does not have a primary key, it is required that the corresponding AR class specify which column(s) should be the primary key by overriding theprimaryKey() method as follows,

public function primaryKey(){    return 'id';    // For composite primary key, return an array like the following    // return array('pk1', 'pk2');}


Creating Record

$post=new Post;$post->title='sample post';$post->content='content for the sample post';$post->create_time=time();$post->save();


If a column is defined with some static default value (e.g. a string, anumber) in the table schema, the corresponding property in the AR instancewill automatically has such a value after the instance is created. One wayto change this default value is by explicitly declaring the property in theAR class:

class Post extends CActiveRecord{    public $title='please enter a title';    ......} $post=new Post;echo $post->title; 


Logging

Tip: While AR allows us to perform database operations without writing cumbersom SQL statements, we often want to know what SQL statements are executed by AR underneath. This can be achieved by turning on thelogging feature of Yii. For example, we can turn on CWebLogRoute in the application configuration, and we will see the executed SQL statements being displayed at the end of each Web page. We can setCDbConnection::enableParamLogging to be true in the application configuration so that the parameter values bound to the SQL statements are also logged.


Reading Record

// find the first row satisfying the specified condition$post=Post::model()->find($condition,$params)// find the row with the specified primary key$post=Post::model()->findByPk($postID,$condition,$params)// find the row with the specified attribute values$post=Post::model()->findByAttributes($attributes,$condition,$params)// find the first row using the specified SQL statement$post=Post::model()->findBySql($sql,$params);

Ex:

// find the row with postID=10$post=Post::model()->find('postID=:postID', array(':postID'=>10));

$criteria=new CDbCriteria;$criteria->select='title';  // only select the 'title' column$criteria->condition='postID=:postID';$criteria->params=array(':postID'=>10);$post=Post::model()->find($criteria); // $params is not needed


$post=Post::model()->find(array(    'select'=>'title',    'condition'=>'postID=:postID',    'params'=>array(':postID'=>10),));


// get the number of rows satisfying the specified condition$n=Post::model()->count($condition,$params);// get the number of rows using the specified SQL statement$n=Post::model()->countBySql($sql,$params);// check if there is at least a row satisfying the specified condition$exists=Post::model()->exists($condition,$params);

$post=Post::model()->findByPk(10);$post->title='new post title';$post->save(); // save the change to database

// update the rows matching the specified conditionPost::model()->updateAll($attributes,$condition,$params);// update the rows matching the specified condition and primary key(s)Post::model()->updateByPk($pk,$attributes,$condition,$params);// update counter columns in the rows satisfying the specified conditionsPost::model()->updateCounters($counters,$condition,$params);


if($post->save()){    // data is valid and is successfully inserted/updated}else{    // data is invalid. call getErrors() to retrieve error messages}

Compare: CActiveRecord::equals(),


CActiveRecord provides a few placeholder methods that can be overriddenin child classes to customize its workflow.

  • beforeValidate andafterValidate: these are invoked before andafter validation is performed.

  • beforeSave andafterSave: these are invoked before and aftersaving an AR instance.

  • beforeDelete andafterDelete: these are invoked before andafter an AR instance is deleted.

  • afterConstruct: this is invoked forevery AR instance created using thenew operator.

  • beforeFind: this is invoked before an AR finderis used to perform a query (e.g.find(), findAll()).

  • afterFind: this is invoked after every ARinstance created as a result of query.

$model=Post::model();$transaction=$model->dbConnection->beginTransaction();try{    // find and save are two steps which may be intervened by another request    // we therefore use a transaction to ensure consistency and integrity    $post=$model->findByPk(10);    $post->title='new post title';    if($post->save())        $transaction->commit();    else        $transaction->rollback();}catch(Exception $e){    $transaction->rollback();    throw $e;}


Named Scopes

class Post extends CActiveRecord{    ......    public function scopes()    {        return array(            'published'=>array(                'condition'=>'status=1',            ),            'recently'=>array(                'order'=>'create_time DESC',                'limit'=>5,            ),        );    }}

$posts=Post::model()->published()->recently()->findAll();

Parameterized Named Scopes

public function recently($limit=5){    $this->getDbCriteria()->mergeWith(array(        'order'=>'create_time DESC',        'limit'=>$limit,    ));    return $this;}

Default Scope


class Content extends CActiveRecord{    public function defaultScope()    {        return array(            'condition'=>"language='".Yii::app()->language."'",        );    }}
$contents=Content::model()->findAll();