• 【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

     本文用菊子曰发布
  • 相关阅读:
    ArcGIS JS 学习笔记1 用ArcGIS JS 实现仿百度地图的距离量测和面积量测
    WGS84,GCJ02, BD09坐标转换
    离线地图切片及使用解决方案
    ArcGIS API for JavaScript 加载独立GeoWebCache发布的Wmts服务
    如何利用已有的切片文件生成TPK
    arcgis api for silverlight(时间感知层)
    arcgis api for silverlight(行为和行动)
    开篇有益
    关于vue项目中表格所遇到的问题(三)
    关于vue项目中表格所遇到的问题(二)
  • 原文地址:https://www.cnblogs.com/xweiwei/p/2780497.html
Copyright © 2020-2023  润新知