第 7 章 dar(Database Active Record)

目录

7.1. 简介
7.2. 配置数据库连接
7.3. 模型
7.3.1. 模型字段
7.3.2. 模型间关联
7.4. 访问模型
7.4.1. 存入数据库
7.4.2. 查询
7.4.3. 删除
7.4.4. 更新
7.4.5. 事务
7.5. 查询条件的参数
7.6. 分页
7.7. dar与三层架构

7.1. 简介

dar是用来管理通过模型管理数据库的模块。以mysql作为例子,通常PHP程序员通过

  1. 直接使用mysql_*或mysqli_*操作数据库,类似于

    $result mysql_result("SELECT * FROM example");
    while (
    $row mysql_fetch_array($result)) {
        
    print_r($row);
    }
  2. 使用PDO操作数据库,和1中例子类似

        $pdo = new PDO("mysql:host=localhost;dbname=example""root""pass");
        
    $stmt $pdo->query("SELECT * FROM tbl_log");
        
    print_r($stmt->fetchAll());

第一种缺乏封装,开发效率低,容错能力差(对于新手来说,很容易出现莫名其妙的错误),第二种是PHP5引入的轻量级的、兼容各种数据库的应用接口,简单易用,通过占位符(?或:name)传入数据,可以不担心SQL注入问题,它完全能自动将参数转义。

现在的PHP开发框架对数据库操作有三种类型的封装:

  1. 将所有语句写入统一的XML文件中,使用分配的ID进行查询(I-F和Prado支持这种做法,都学习了IBATIS),XML:

    <?xml version="1.0" encoding="utf-8" ?>
    <sqlMap namespace="blog">
        <select id="query">
            SELECT * FROM example.blog WHERE id=:id LIMIT 1
        </select>
        

        <insert id="insert">
            INSERT INTO example.blog (caption,submit_time,content) VALUES (:caption,NOW(),:content)
        </insert>
        

        <update id="update">
             UPDATE example.blog SET caption=:caption,content=:content WHERE id=:id
        </update>
        

        <delete id="delete">
            DELETE FROM example.blog WHERE id=:id
        </delete>
        
    </sqlMap>

    然后使用以下程序查询:

    $sqlmap->fetchArray("blog.query"$params);
    $sqlmap->insert("blog.insert"$params);
    $sqlmap->update("blog.update"$params);
    $sqlmap->delete("blog.delete"$params)

    这种做法的好处是,将SQL统一管理起来,降低了维护成本。

  2. 将表对应一个数组,操作时直接传入数据即可,开发接口形如:

        $array = array(
            
    "name" => "tom",
            
    "age" => 20,
            
    "job" => "worker"
        
    );
        
    $array $model->find(1);
        
    $model->save($array);
        
    $model->update($array);
        
    $model->delete($array);
  3. 将表对应一个对象,操作数据库时只关注对象(主要学习了Hibernate):

    $model model::manager()->find(1);
    $model->save();
    $model->update();
    $model->delete()

他们都实现了传说中的CRUD(create,read,update,delete),大大简化了数据的操作,提高了开发效率;又无需再写大量的SQL语句在程序中,提高了可维护性。

I-F使用模型来操作数据库,使用PHP类来表达模型,模型一旦建立,就无需再关心原有的表结构和表数据形式,95%以上情况无需再写恼人的SQL。I-F目前只封装了mysql驱动,并将在0.2版本中提供更完整的数据库驱动。

很担心的问:执行效率如何?

理论上讲封装越多,效率越低,所以对于单个查询来说直接使用SQL查询当然要比使用模型来得快,但是,当要大批量、大数据量查询时,单纯的SQL很难做到:

  1. 对数据进行缓存

  2. 对已经查询出来的数据不再查询

  3. 在需要的时候才会查询数据(惰加载)

  4. 数据表变动时,只需简单地修改模型的配置

  5. 添加虚拟字段

而模型就可以轻易管理这些,不仅降低了程序的复杂度,提高了开发效率,而且还能通过各种方式提高运行效率。

模型的封装其实是使我们更多地关注业务逻辑的开发,而不是纠缠于一堆有很多重复的SQL上。所以,越来越多地framework会提供这种模块已经是几个可以用于WEB开发的语言的必然(PHP,RoR,Python等等)。