<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://unfoldingneurons.com/"
	>

<channel>
	<title>我是妖怪 &#187; DataMapper</title>
	<atom:link href="http://www.dualface.com/index.php/archives/tag/datamapper/feed" rel="self" type="application/rss+xml" />
	<link>http://www.dualface.com</link>
	<description>Fire and Motion</description>
	<lastBuildDate>Sat, 04 Sep 2010 03:33:17 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>从程序设计上减少不必要的并发更新冲突</title>
		<link>http://www.dualface.com/index.php/archives/1042</link>
		<comments>http://www.dualface.com/index.php/archives/1042#comments</comments>
		<pubDate>Sat, 04 Sep 2010 03:10:57 +0000</pubDate>
		<dc:creator>dualface</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[DataMapper]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.dualface.com/?p=1042</guid>
		<description><![CDATA[有多个请求更新同一条数据库记录时，就可能出现冲突。
比如在农场游戏中，有一块地现在种植了20朵玫瑰。同一时间玩家A采集了2朵，玩家B采集3朵，玩家C采集了4朵。此时三个请求一起到达，对数据库的更新就很可能出现问题。

我们使用如下的代码：

// player_id: 玩家ID
// field_inx: 某一块地的索引
// pick: 要采集的量
$field = Field::find_one(array(&#039;player_id&#039; =&#62; $player_id, &#039;field_inx&#039; =&#62; $field_inx));
if ($field-&#62;quantity &#60; $pick)
{
    .... 土地的作物剩余数量不足
    return ...;
}

$field-&#62;quantity -= $pick;
$field-&#62;save();

假设玩家A采集2朵时，$field 读取出来的 quantity 值是 20，则 save() 后，quantity 的新值是 18。如果在处理玩家A的请求时，程序执行到 save() 之前，服务器就开始处理玩家B采集3朵的请求，则玩家B读取到的 quantity 值将是玩家A更新前的值。两个请求谁最后调用save()，数据库中就是哪个请求写入的值。最终结果是两个玩家分别采集了 2 朵和 3 朵，但剩余数量却不是 15 朵。
要避免此问题，一种常见的解决办法就是使用数据库事务。
当开启事务后，代码如下：

// $adapter 是数据库访问对象
$adapter-&#62;begin(); // 开启事务

// player_id: 玩家ID
// field_inx: 某一块地的索引
// [...]]]></description>
		<wfw:commentRss>http://www.dualface.com/index.php/archives/1042/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>QeePHP 2.2: Working for DataMapper</title>
		<link>http://www.dualface.com/index.php/archives/82</link>
		<comments>http://www.dualface.com/index.php/archives/82#comments</comments>
		<pubDate>Sat, 30 May 2009 08:29:53 +0000</pubDate>
		<dc:creator>dualface</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[DataMapper]]></category>
		<category><![CDATA[ORM]]></category>

		<guid isPermaLink="false">http://www.dualface.com/?p=82</guid>
		<description><![CDATA[在 QeePHP 2.2 中，将新增一个组件：DataMapper。
DataMapper 与现在的 ActiveRecord 一样是 ORM 服务组件。不同之处在于 DataMapper 更强调面向对象的风格，并且提供了一系列的自动化工具来提高开发效率。

有关 DataMapper 的设计思想，请阅读“Sexy ORM”。
经过努力，对于模型的解析已经接近完成。
BaseMember（源代码） 是所有会员模型的基础类，定义了所有类型会员都具备的基础属性和关联。而 Member（源代码） 是更一般化的会员，提供了针对会员领域的特定设置。
由于 DataMapper 对继承特性的良好支持，我们可以很容易的将领域模型进行拆分，拆分后的每一个领域模型都只关注自己应该承担的责任：

从源代码看，适用于 DataMapper 的模型更清晰易读。领域中必须的概念和内容都可以通过源代码来呈现，避免了现在 ActiveRecord 模式导致的数据结构和行为被人为分割的问题。
DataMapper 主要依赖于 PHP5 的反射来解析模型类。解析结果包含了模型的方方面面。由于解析结果可以轻松的缓存，因此 DataMapper 对模型类的解析并不会导致性能问题。
DataMapper 组件接下来的工作：

ActiveRecord 和 DataMapper 将使用同一个 ORM 基础架构，这样可以满足不同需求的开发者，并且能够充分保障已有的代码资源；
为 DataMapper 提供一系列的自动化工具，完成诸如模型类转换为数据表设计等工作；
在 WebSetup 中为 DataMapper 提供支持。

总的来说，我们希望 QeePHP 2.2 更符合面向对象开发的原则和实践，能够为开发者提供更好的开发体验和基础支持。当然，我们也会保证 QeePHP 2.2 的性能不会出现下降（实际上在 ORM 部分，性能应该会有显著的提高）。
]]></description>
		<wfw:commentRss>http://www.dualface.com/index.php/archives/82/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Sexy ORM</title>
		<link>http://www.dualface.com/index.php/archives/45</link>
		<comments>http://www.dualface.com/index.php/archives/45#comments</comments>
		<pubDate>Fri, 27 Mar 2009 03:15:21 +0000</pubDate>
		<dc:creator>dualface</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[DataMapper]]></category>
		<category><![CDATA[ORM]]></category>

		<guid isPermaLink="false">http://www.dualface.com/?p=45</guid>
		<description><![CDATA[Sexy ORM &#8212; 全面革新的 ORM 系统
前言：
QeePHP 提供了一个全功能的 ORM 系统，能够完善处理各种对象间的复杂关系，为开发者采用面向对象设计来解决业务问题提供了有力的支持。不过实践中，我们也发现 QeePHP 现有的 ORM 系统存在各种不足。因此，全面革新 ORM 系统成为了一项重要的任务。该任务名为：Sexy ORM。
&#160;
Sexy ORM 是 QeePHP 下一个版本的重点之一，目标是为 QeePHP 提供一个更容易理解和使用的 ORM 架构。
在 QeePHP 现有 ORM 架构的基础之上，Sexy ORM 更符合面向对象开发的思想，并且为团队协作和高效开发提供了更多的支持。

清晰的模型定义
QeePHP 目前使用的 ORM 中，模型的属性、关联等是在模型类的 __define() 静态方法中定义的。
这种定义方式不够直观，而且还有下列弊端：

违背了面向对象设计的初衷，强迫开发者回到以数据库为中心的设计方式；
模型代码中的属性定义不完整，如果不查看数据表无法知道模型到底有哪些属性；
当模型或数据表改变时，很可能出现模型与数据表不一致的情况；
无法通过反射等机制完成模型的自动化维护，给团队协作带来了困难。

在 Sexy ORM 中，将采用更清晰的模型定义方式：

&#60; ?php

/**
 * 作者
 *
 * @table authors
 */
class Author extends QModel
{
    /**
   [...]]]></description>
		<wfw:commentRss>http://www.dualface.com/index.php/archives/45/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>
<!-- This Quick Cache file was built for (  www.dualface.com/index.php/archives/tag/datamapper/feed ) in 0.84762 seconds, on Sep 8th, 2010 at 1:55 pm UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on Sep 8th, 2010 at 2:55 pm UTC -->