数据映射器模式和其他对象的自动更新

时间:2009-01-30 21:28:34

标签: php datamapper

我正在使用数据映射器模式构建一个PHP应用程序,以将我的数据库与域对象分开。我有一个mapper类,它根据来自DB的数据返回Site对象,并接受现有的Site对象以保存回DB。

我的问题是,在系统中,所有站点中的一个(并且只有一个)必须被标记为“主要”站点,这意味着如果我将其中一个设置为主要站点,我希望能够自动取消设置当前主要。

所以,比如:

$mapper = new Site_Mapper();
$site = $mapper->fetch(2);
$site->isPrimary = true;
$mapper->save($site);

会在后台以某种方式自动执行此操作:

$mapper = new Site_Mapper();
$site = $mapper->fetch(1);
$site->isPrimary = false;
$mapper->save($site);

问题是,自动更新现有主站点的逻辑应该放在哪里?它必须在将对象保存回数据库之后发生,而不是之前,以防数据库查询失败并且您没有站点作为主站点。

干杯, 千斤顶

2 个答案:

答案 0 :(得分:1)

听起来像数据库触发器的工作。

DELIMITER $$

CREATE TRIGGER test_trigger AFTER INSERT ON table
  FOR EACH ROW BEGIN
    IF NEW.isPrimary = 1 THEN 
       UPDATE table 
       SET isPrimary = 0
       WHERE id <> NEW.id;
    END IF;
  END$$

DELIMITER ;

答案 1 :(得分:1)

我个人认为将附加更新逻辑放在Site_Mapper类中是最有意义的,特别是考虑到你在两个实例中处理相同的表/映射器。您可以简单地覆盖save($ siteObj)方法,使其工作方式如下:

 public function save($siteObj) 
 {
     // Save the passed object.

     $sql = "UPDATE site SET isPrimary = 1 WHERE id != ?";

     $stmt = new PDO_Statement($sql);

     $stmt->execute($siteObj->id);

 }

显然你可以创建一个自定义的save()函数,或者更平滑地创建它,或者你可以使用if比较来确保你真的需要运行更新语句。