hh168

hh168

www.hkyizu.com

  • 财富值55
  • 威望值0
  • 总积分55

个人信息

  • 打个标签 收藏下

    1. 定义 AR 类
      要访问一个数据表,我们首先需要通过集成 CActiveRecord 定义一个 AR 类。 每个 AR 类代表一个单独的数据表,一个 AR 实例则代表那个表中的一行。 如下例子演示了代表 tbl_post 表的 AR 类的最简代码:
    class Post extends CActiveRecord
    {
        public static function model($className=__CLASS__)
        {
            return parent::model($className);
        }
     
        public function tableName()
        {
            return 'tbl_post';
        }
    }
    

    提示: 由于 AR 类经常在多处被引用,我们可以导入包含 AR 类的整个目录,而不是一个个导入。 例如,如果我们所有的 AR 类文件都在 protected/models 目录中,我们可以配置应用如下:

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

    默认情况下,AR 类的名字和数据表的名字相同。如果不同,请覆盖 tableName() 方法。 model() 方法为每个 AR 类声明为如此(稍后解释)。

    信息: 要使用 1.1.0 版本中引入的 表前缀功能 AR 类的 tableName() 方法可以通过如下方式覆盖

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

    这就是说,我们将返回通过双大括号括起来的没有前缀的表名,而不是完整的表的名字。

    数据表行中列的值可以作为相应 AR 实例的属性访问。例如,如下代码设置了 title 列 (属性):

    $post=new Post;
    $post->title='a sample post';
    

    虽然我们从未在 Post 类中显式定义属性 title,我们还是可以通过上述代码访问。 这是因为 title 是tbl_post 表中的一个列,CActiveRecord 通过PHP的 __get() 魔术方法使其成为一个可访问的属性。 如果我们尝试以同样的方式访问一个不存在的列,将会抛出一个异常。

    信息: 此指南中,我们在表名和列名中均使用了小写字母。 这是因为不同的 DBMS 处理大小写的方式不同。 例如,PostgreSQL 默认情况下对列的名字大小写不敏感,而且我们必须在一个查询条件中用引号将大小写混合的列名引起来。 使用小写字母可以帮助我们避免此问题。

    AR 依靠表中良好定义的主键。如果一个表没有主键,则必须在相应的 AR 类中通过如下方式覆盖 primaryKey()方法指定哪一列或哪几列作为主键。

    public function primaryKey()
    {
        return 'id';
        // 对于复合主键,要返回一个类似如下的数组
        // return array('pk1', 'pk2');
    }
    
    1. 创建记录
      要向数据表中插入新行,我们要创建一个相应 AR 类的实例,设置其与表的列相关的属性,然后调用 save() 方法完成插入:
    $post=new Post;
    $post->title='sample post';
    $post->content='content for the sample post';
    $post->create_time=time();
    $post->save();
    

    如果表的主键是自增的,在插入完成后,AR 实例将包含一个更新的主键。在上面的例子中, id 属性将反映出新插入帖子的主键值,即使我们从未显式地改变它。

    如果一个列在表结构中使用了静态默认值(例如一个字符串,一个数字)定义。则 AR 实例中相应的属性将在此实例创建时自动含有此默认值。改变此默认值的一个方式就是在 AR 类中显示定义此属性:

    class Post extends CActiveRecord
    {
        public $title='please enter a title';
        ......
    }
     
    $post=new Post;
    echo $post->title;  // 这儿将显示: please enter a title
    

    从版本 1.0.2 起,记录在保存(插入或更新)到数据库之前,其属性可以赋值为 CDbExpression 类型。 例如,为保存一个由 MySQL 的 NOW() 函数返回的时间戳,我们可以使用如下代码:

    $post=new Post;
    $post->create_time=new CDbExpression('NOW()');
    // $post->create_time='NOW()'; 不会起作用,因为
    // 'NOW()' 将会被作为一个字符串处理。
    $post->save();
    

    提示: 由于 AR 允许我们无需写一大堆 SQL 语句就能执行数据库操作, 我们经常会想知道 AR 在背后到底执行了什么 SQL 语句。这可以通过开启 Yii 的 日志功能 实现。例如,我们在应用配置中开启了CWebLogRoute ,我们将会在每个网页的最后看到执行过的 SQL 语句。 从 1.0.5 版本起,我们可以在应用配置中设置 CDbConnection::enableParamLogging 为 true ,这样绑定在 SQL 语句中的参数值也会被记录。

    1. 读取记录
      要读取数据表中的数据,我们可以通过如下方式调用 find 系列方法中的一种:
    // 查找满足指定条件的结果中的第一行
    $post=Post::model()->find($condition,$params);
    // 查找具有指定主键值的那一行
    $post=Post::model()->findByPk($postID,$condition,$params);
    // 查找具有指定属性值的行
    $post=Post::model()->findByAttributes($attributes,$condition,$params);
    // 通过指定的 SQL 语句查找结果中的第一行
    $post=Post::model()->findBySql($sql,$params);
    

    如上所示,我们通过 Post::model() 调用 find 方法。 请记住,静态方法 model() 是每个 AR 类所必须的。 此方法返回在对象上下文中的一个用于访问类级别方法(类似于静态类方法的东西)的 AR 实例。

    如果 find 方法找到了一个满足查询条件的行,它将返回一个 Post 实例,实例的属性含有数据表行中相应列的值。 然后我们就可以像读取普通对象的属性那样读取载入的值,例如 echo $post->title;。

    如果使用给定的查询条件在数据库中没有找到任何东西, find 方法将返回 null 。

    调用 find 时,我们使用 $condition 和 $params 指定查询条件。此处 $condition 可以是 SQL 语句中的WHERE 字符串,$params 则是一个参数数组,其中的值应绑定到 $condation 中的占位符。例如:

    // 查找 postID=10 的那一行
    $post=Post::model()->find('postID=:postID', array(':postID'=>10));
    

    注意: 在上面的例子中,我们可能需要在特定的 DBMS 中将 postID 列的引用进行转义。 例如,如果我们使用 PostgreSQL,我们必须将此表达式写为 "postID"=:postID,因为 PostgreSQL 在默认情况下对列名大小写不敏感。

    我们也可以使用 $condition 指定更复杂的查询条件。 不使用字符串,我们可以让 $condition 成为一个CDbCriteria 的实例,它允许我们指定不限于 WHERE 的条件。 例如:

    $criteria=new CDbCriteria;
    $criteria->select='title';  // 只选择 'title' 列
    $criteria->condition='postID=:postID';
    $criteria->params=array(':postID'=>10);
    $post=Post::model()->find($criteria); // $params 不需要了
    

    注意,当使用 CDbCriteria 作为查询条件时,$params 参数不再需要了,因为它可以在 CDbCriteria 中指定,就像上面那样。

    一种替代 CDbCriteria 的方法是给 find 方法传递一个数组。 数组的键和值各自对应标准(criterion)的属性名和值,上面的例子可以重写为如下:

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

    信息: 当一个查询条件是关于按指定的值匹配几个列时,我们可以使用 findByAttributes()。我们使$attributes 参数是一个以列名做索引的值的数组。在一些框架中,此任务可以通过调用类似findByNameAndTitle 的方法实现。虽然此方法看起来很诱人, 但它常常引起混淆,冲突和比如列名大小写敏感的问题。

    当有多行数据匹配指定的查询条件时,我们可以通过下面的 findAll 方法将他们全部带回。 每个都有其各自的find 方法,就像我们已经讲过的那样。

    // 查找满足指定条件的所有行
    $posts=Post::model()->findAll($condition,$params);
    // 查找带有指定主键的所有行
    $posts=Post::model()->findAllByPk($postIDs,$condition,$params);
    // 查找带有指定属性值的所有行
    $posts=Post::model()->findAllByAttributes($attributes,$condition,$params);
    // 通过指定的SQL语句查找所有行
    $posts=Post::model()->findAllBySql($sql,$params);
    

    如果没有任何东西符合查询条件,findAll 将返回一个空数组。这跟 find 不同,find 会在没有找到什么东西时返回 null。

    除了上面讲述的 find 和 findAll 方法,为了方便,(Yii)还提供了如下方法:

    // 获取满足指定条件的行数
    $n=Post::model()->count($condition,$params);
    // 通过指定的 SQL 获取结果行数
    $n=Post::model()->countBySql($sql,$params);
    // 检查是否至少有一行复合指定的条件
    $exists=Post::model()->exists($condition,$params);
    
    1. 建立数据库连接
      AR 依靠一个数据库连接以执行数据库相关的操作。默认情况下, 它假定 db 应用组件提供了所需的CDbConnection 数据库连接实例。如下应用配置提供了一个例子:
    return array(
        'components'=>array(
            'db'=>array(
                'class'=>'system.db.CDbConnection',
                'connectionString'=>'sqlite:path/to/dbfile',
                // 开启表结构缓存(schema caching)提高性能
                // 'schemaCachingDuration'=>3600,
            ),
        ),
    );
    

    提示: 由于 Active Record 依靠表的元数据(metadata)测定列的信息,读取元数据并解析需要时间。 如果你数据库的表结构很少改动,你应该通过配置 CDbConnection::schemaCachingDuration 属性的值为一个大于零的值开启表结构缓存。

    对 AR 的支持受 DBMS 的限制,当前只支持下列几种 DBMS:

    MySQL 4.1 或更高版本
    PostgreSQL 7.3 或更高版本
    SQLite 2 和 3
    Microsoft SQL Server 2000 或更高版本
    Oracle
    注意: 1.0.4 版开始支持 Microsoft SQL Server;1.0.5 版开始支持 Oracle。

    如果你想使用一个不是 db 的应用组件,或者如果你想使用 AR 处理多个数据库,你应该覆盖CActiveRecord::getDbConnection()。 CActiveRecord 类是所有 AR 类的基类。

    提示: 通过 AR 使用多个数据库有两种方式。如果数据库的结构不同,你可以创建不同的 AR 基类实现不同的 getDbConnection()。否则,动态改变静态变量 CActiveRecord::db 是一个好主意。

  • 连接为空,请核实.

  • 既然无关与技术,那就不要金币了,行不?

  • 多谢楼主的帖子,赞一个!!

  • 偶想参加

职场新人 等级规则
55/100
资料完整度
40/100
用户活跃度
0/100

Ta的关注

0

Ta的粉丝

0

Ta的访客

0