PHP设计模式-数据访问对象模式

        在PHP开发中,我们经常会与数据库打交道(本例中以mysql为例),尤其是一些数据库的增删改查操作,是经常要用到的。假定,我们有一个mysql数据库,有服务器名$host, 数据库用户名$user, 数据库密码$pass及数据库$test. 

        现在我们要连接test数据库,并执行一个建表语句,通常会这么

//连接数据库
$conn = mysql_connect($host, $user, $pass);
mysql_select_db($dbName, $conn);

//建立user表
$sql  = "CREATE TABLE user (id PRIMARY KEY, name varchar(32))";
mysql_query($sql, $conn);
        要查询表里的内容,我们会:

//连接数据库
$conn = mysql_connect($host, $user, $pass);
mysql_select_db($dbName, $conn);

$sql = "SELECT * FROM user";
$result = mysql_query($sql, $conn);
$ret = array();
while ($row = mysql_fetch_assoc($result)) {
	$ret[] = $row;
}
        我们看到,所有数据库的操作都需要一个连接对象, 连接对象的生成需要数据库的一些基础信息(包括host,用户名,密码和数据库名)。那我们把这一块儿抽象出来:

class Db_Mysql
{

    //数据库连接对象
    protected $_conn;

    //初始化数据库连接
    public function __construct($host, $user, $pass, $dbName)
    {
        $this->_conn = mysql_connect($host, $user, $pass);
        mysql_select_db($dbName);
    }
}
        这时候我们做任何的操作都只需要对这个连接对象进行操作即可。那我们再回忆一下,其实我们经常对数据库的常用操作有执行sql语句,插入,修改,删除,读取数据。那我们就把这个几个方法也抽象出来。
class Db_Mysql
{

    //数据库连接对象
    protected $_conn;

    //初始化数据库连接
    public function __construct($host, $user, $pass, $dbName)
    {
        $this->_conn = mysql_connect($host, $user, $pass);
        mysql_select_db($dbName, $this->_conn);
    }

    //插入操作
    public function insert($data)
    {
		//传入一个数组,可以插入数据
    }

    //修改操作
    public function update($data, $where)
    {
		//根据查询条件,修改数据
    }

    //删除操作
    public function delete($where)
    {
		//根据查询条件,删除数据
    }

    //执行sql操作
    public function execute($sql)
    {
		$this->getConnection()->query($sql);
    }
	
	//根据sql读取数据
	public function fetchBySql($sql)
	{
		$ret = array();
		$result = $this->execute($sql);
		if (empty($result)) {
			return $ret;	
		}
		while ($row = mysql_fetch_assoc($result)) {
			$ret[] = $row;
		}
		return $ret;
	}
	
	//获取连接
	public function getConnection()
	{
		return $this->_conn;	
	}
	
	//获取表名
	public function getDbName()
	{
		return $this->_dbName;	
	}
}
        由于我们只关心架构,因此,很多地方的具体的实现代码省略掉了。当我们需要对一个数据库进行操作,只要新建一个类,继承Db_Mysql类,就可以无需重复书写大量的数据库操作方法。此时,我们再试着实现刚开始的数据库操作的例子.

class Test extends Db_Mysql
{

	//数据库名
	protected $_dbName = "test";
	
	//表名
	protected $_tableName = "user";
	
	//初始化
	public function __construct($host, $user, $pass)
	{
		parent::__construct($host, $user, $pass, $this->getDbName());
	}
}

//建表
$test = new Test($host, $user, $pass);
$sql  = "CREATE TABLE user (id PRIMARY KEY, name varchar(32))";
$test->execute($sql);

//获取数据
$sql = "SELECT * FROM ".$test->getTableName();
$result = $test->fetchBySql($sql);

//再执行一个sql设置字符集
$sql = "SET NAMES utf8";
$test->execute($sql);
        我们发现,很多的数据库连接的初始化,数据库选择,数据获取等操作,不用再重复书写了。我们把这种对数据的访问的操作的封装叫做数据访问对象模式。其实数据访问对象模式除了用在数据库访问上。还可以用在很多地方,例如:我们要建立一个文件缓存系统,就涉及到缓存的创建,读取,更新等操作,我们也可以把这些操作抽象出来,方便操作,而且不用重复书写代码大量代码,有时候也能起到让调用者无需关心实现细节的目的。
        同时,细心的同学也会发现,其实增删改查这些操作是不应该和Db混在一起的,这些都是表操作。真正的一个好的设计应该是数据库对象,表对象,SQL语句对象,以及数据对象区分开来,尤其是语句对象,它要实现查询域,查询条件,排序方式,分组等条件的抽象。但这一章节,只是为了介绍数据访问对象模式的基本原理。而且本文中很多操作性的代码都省略了。目的只是为了能快速了解这个数据访问对象模式,而免受过多代码的干扰。

        对数据库的操作设计,个人感觉ZendFramewordk的设计很到位。从设计模式的角度上来看,它合理地利用了简单工厂,适配器,数据访问对象,迭代器等模式。有兴趣的朋友可以看一下它的源码.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值