接下来,让我们写一些代码来执行它。
class BookmarkMapper { //... const INSERT_SQL = “ insert into bookmark (url, name, description, tag, created, updated) values (?, ?, ?, ?, now(), now()) “; public function save($bookmark) { $rs = $this->conn->execute( self::INSERT_SQL ,array( $bookmark->getUrl() ,$bookmark->getName() ,$bookmark->getDesc() ,$bookmark->getGroup())); } } |
一个对象的常量存储了插入数据的语句,并且代码“自动”把Bookmark 的accessor方法映射到相对应的SQL语句。
现在看起来都齐全了,但是我们还需要做两个事情:处理数据库错误的代码和根据数据库的改变更改初始化的时候设置后者更改$bookmark的属性。
class BookmarkMapper { //... public function save($bookmark) { $rs = $this->conn->execute( self::INSERT_SQL ,array( $bookmark->getUrl() ,$bookmark->getName() ,$bookmark->getDesc() ,$bookmark->getGroup())); if ($rs) { $inserted = $this->findById($this->conn->Insert_ID()); //clean up database related fields in parameter instance $bookmark->setId($inserted->getId()); $bookmark->setCrtTime($inserted->getCrtTime()); $bookmark->setModTime($inserted->getModTime()); } else { throw new Exception(‘DB Error: ‘.$this->conn->errorMsg()); } } } |
findById() 看起来内容还很少,它的作用是找到并返回匹配ID的Bookmark 实例。本质上来说, BookmarkMapper 用来插入新的Bookmark,从数据库提取数据,并且根据正确的值来设置何时的属性值。而且因为Bookmark 实例自己就是参数并可以被更新,所以必须要返回任何值。
让我们来看下findById()的的详细内容。你可以使用同样的BaseTestCase(前面的Table Data Gateway章节):
class BookmarkMapperTestCase extends BaseTestCase { // ... function testFindById() { $mapper = new BookmarkMapper($this->conn); $this->addSeveralBookmarks($mapper); $this->assertIsA( $bookmark = $mapper->findById(1) , ‘Bookmark’); $this->assertEqual(1, $bookmark->getId()); } } |
从技术上来说,addSeveralBookmarks() 必须等待findById()工作正常再开始工作。(看save()方法里面的代码就知道了),我们等下再来研究addSeveralBookmarks()。
class BookmarkMapper { |
createBookmarkFromRow()。 |
class BookmarkMapper { |
首先,数据从数据库提取出来;随后,建立一个Bookmark的实例。然后,对于映射的每一个部分,代码找到合适的setter方法并把数据行的值传递给setter方法。Bookmark实例,添加了数据库的数据后,用findById()取出。
现在,让我们看下BookmarkMapper::add()方法,通过BaseTestCase::addSeveralBookmarks()实现。通过一个测试用例,我们可以发现他们都是在表里面创建一个新的行并且返回Bookmark类的一个拥有实际数据的实例。
class BookmarkMapperTestCase extends BaseTestCase { |
class BookmarkMapper { // ... public function add($url, $name, $description, $group) { $bookmark = new Bookmark; $bookmark->setUrl($url); $bookmark->setName($name); $bookmark->setDesc($description); $bookmark->setGroup($group); $this->save($bookmark); return $bookmark; } } |
这个与动态的记录ActiveRecordTestCase::add()是很类似的,方便使用。但是这里它已经被加入到数据映射里面而不是测试用例,这样在整个项目里面都可以使用它。
延伸阅读:
从魔兽看PHP设计模式
《PHP设计模式介绍》导言
PHP设计模式介绍 第一章 编程惯用法
PHP设计模式介绍 第二章 值对象模式
PHP设计模式介绍 第三章 工厂模式
PHP设计模式介绍 第四章 单件模式
PHP设计模式介绍 第五章 注册模式
PHP设计模式介绍 第六章 伪对象模式
PHP设计模式介绍 第七章 策略模式
PHP设计模式介绍 第八章 迭代器模式
PHP设计模式介绍 第九章 观测模式
PHP设计模式介绍 第十章 规范模式
PHP设计模式介绍 第十一章 代理模式
PHP设计模式介绍 第十二章 装饰器模式
PHP设计模式介绍 第十三章 适配器模式
PHP设计模式介绍 第十四章 动态记录模式
PHP设计模式介绍 第十五章 表数据网关模式