我正在使用数据映射器模式构建一个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);
问题是,自动更新现有主站点的逻辑应该放在哪里?它必须在将对象保存回数据库之后发生,而不是之前,以防数据库查询失败并且您没有站点作为主站点。
干杯, 千斤顶
答案 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比较来确保你真的需要运行更新语句。