【Yii】数据库读写方法:AR模型和DAO方法


一、AR模型方法

AR模型是ORM方式的一种,其将SQL查询进行封装,使得数据库读写更加方便便捷。其中一个AR类代表数据库中的一张表。

1.类的定义(Model模型)

定义方式如下:

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

这是一个Model类的最小代码。

2.新增记录

 

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

 

3.查询

查询语句比较复杂,主要有四种。

 

//  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);

 

其中$condition部分就是SQL语句的WHERE部分,$params就是$condition里面需要的参数。示例:

 

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

 

同时也可以使用CDbCriteria类来配置查询条件。示例如下:

 

$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

 

此时就无需$params参数了。

上述是查询单条记录,如果要查询多条记录则使用:

 

//  find all rows satisfying the specified condition
$posts=Post::model()->findAll( $condition, $params);
//  find all rows with the specified primary keys
$posts=Post::model()->findAllByPk( $postIDs, $condition, $params);
//  find all rows with the specified attribute values
$posts=Post::model()->findAllByAttributes( $attributes, $condition, $params);
//  find all rows using the specified SQL statement
$posts=Post::model()->findAllBySql( $sql, $params);

 

4.更新记录

更新记录也可以用save()函数。AR模型会智能判定,若对象由new创建则新建记录,若对象是从数据库中的查询结果,则save函数就变成了更新。

然而更新也有特定的函数:

//  update the rows matching the specified condition
Post::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 conditions
Post::model()->updateCounters( $counters, $condition, $params);

 

5.删除记录

先查询后删除:

 

$post=Post::model()->findByPk(10);  //  assuming there is a post whose ID is 10
$post->delete();  //  delete the row from the database table

 

直接删除:

//  delete the rows matching the specified condition
Post::model()->deleteAll( $condition, $params);
//  delete the rows matching the specified condition and primary key(s)
Post::model()->deleteByPk( $pk, $condition, $params);

 

6.从表单直接提交到数据库

如果数据表的项太多,插入新记录的时候参数列表可能会很长,这时候可以使用attributes属性来承接由表单POST过来的参数。(未测试)

 

//  assume $_POST['Post'] is an array of column values indexed by column names
$post->attributes= $_POST['Post'];
$post->save();

 

7.函数重载

在执行记录的时候可以伴随着函数调用,这些函数主要有:beforeValidate, afterValidate, beforeSave, afterSave, beforeDelete, afterDelete, afterConstruct, beforeFind, afterFind, 函数名可以看出是什么意思了。

8. 使用事务

事务可以将读写操作作为一个整体进行,有效防止数据库读写出错。

 

$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';
     $post->save();
     $transaction->commit();
}
catch( Exception  $e)
{
     $transaction->rollback();
}

 

二、DAO使用

DAO(数据访问对象)对访问存储在不同数据库管理系统(DBMS)中的数据提供了一个通用的API。因此,在将底层 DBMS 更换为另一个时,无需修改使用了 DAO 访问数据的代码。

上面看到AR的方式很方便和便捷,然而其只能处理简单数据模型,如果需要读写多个数据表或者设计联合查询,AR方式往往很有限,这时候就需要使用DAO方式。

1. 建立连接

 

$connection= new CDbConnection( $dsn, $username, $password);
//  建立连接。你可以使用  try...catch 捕获可能抛出的异常
$connection->active= true;
......
$connection->active= false;   //  关闭连接

 

2.执行SQL语句

 

$connection=Yii::app()->db;    //  假设你已经建立了一个 "db" 连接
// 如果没有,你可能需要显式建立一个连接:
// $connection=new CDbConnection($dsn,$username,$password);

$command= $connection->createCommand( $sql);
//  如果需要,此 SQL 语句可通过如下方式修改:
// $command->text=$newSQL;

$rowCount= $command->execute();    //  执行无查询 SQL
$dataReader= $command->query();    //  执行一个 SQL 查询
$rows= $command->queryAll();       //  查询并返回结果中的所有行
$row= $command->queryRow();        //  查询并返回结果中的第一行
$column= $command->queryColumn();  //  查询并返回结果中的第一列
$value= $command->queryScalar();   //  查询并返回结果中第一行的第一个字段

 

3.获取查询结果

 

$dataReader= $command->query();
//  重复调用 read() 直到它返回 false
while(( $row= $dataReader->read())!== false) { ... }
//  使用 foreach 遍历数据中的每一行
foreach( $dataReader  as  $row) { ... }
//  一次性提取所有行到一个数组
$rows= $dataReader->readAll();

 

4.使用事务

 

$transaction= $connection->beginTransaction();
try
{
     $connection->createCommand( $sql1)->execute();
     $connection->createCommand( $sql2)->execute();
     // .... other SQL executions
     $transaction->commit();
}
catch( Exception  $e//  如果有一条查询失败,则会抛出异常
{
     $transaction->rollBack();
}

 

5.绑定列

绑定列可以让当前查询结果和一个变量绑定,方便操作。

 

$sql="SELECT username, email FROM tbl_user";
$dataReader= $connection->createCommand( $sql)->query();
//  使用 $username 变量绑定第一列 (username)
$dataReader->bindColumn(1, $username);
//  使用 $email 变量绑定第二列 (email)
$dataReader->bindColumn(2, $email);
while( $dataReader->read()!== false)
{
     //  $username 和 $email 含有当前行中的 username 和 email
}

 

三、参考文章:

1. 数据访问对象(DAO):http://www.yiiframework.com/doc/guide/1.1/zh_cn/database.dao

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

3.PHP Yii 框架的数据库操作笔记一、查询,更新,删除的方法(AR模式):http://hi.baidu.com/caoxin_rain/item/df9da2362d6038342f0f8161

4.Yii AR Model 查询:http://www.cnblogs.com/likwo/archive/2011/09/01/2162017.html

 本文用 菊子曰发布


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM