我正在编写一个需要在应用程序层内部进行主/从切换的应用程序。现在,我在创建映射器时实例化Zend_Db_Table对象,然后将DefaultAdapter设置为从属。
现在在基本映射器类的内部,我有以下方法:
public function useWriteAdapter()
{
if(Zend_Db_Table_Abstract::getDefaultAdapter() != $this->_writeDb)
{
Zend_Db_Table_Abstract::setDefaultAdapter($this->_writeDb);
$this->_tableGateway = new Zend_Db_Table($this->_tableName);
}
}
我需要对此进行健全性检查。我认为开销不会太大,我只是怀疑必须有更好的方法。
Zend_Db_Table_Row_Abstract
类型的对象会记住产生它的Table对象。但是您可以在调用save()
之前更改关联的表。
$readDb = Zend_Db::factory(...); // replica
$writeDb = Zend_Db::factory(...); // master
Zend_Db_Table::setDefaultAdapter($readDb);
$myReadTable = new MyTable(); // use default adapter
$myWriteTable = new MyTable($writeDb);
$row = $myTable->find(1234)->current();
$row->column1 = 'value';
$row->setTable($myWriteTable);
$row->save();
怎么样扩展您执行启动的基类?
class My_Db_Table extends Zend_Db_Table
{
function init()
{
if (....) {
// set the default adaptor to the write-DB-master
}
parent::init();
}
}
// all your models then extend My_Db_Table instead of Zend_Db_Table
尽管您很可能已经提出了一个解决方案,但我仍会以我的方式发布它:我一直在寻找相同问题的解决方案,并提出了将其逻辑放入适配器的想法。
我扩展了Zend_Db_Adapter_Abstract并添加了布尔属性$ writes。我也为此添加了公共getter和setter方法。
我的适配器保存两个不同的数据库配置/连接:一个用于主数据库(用于写入),一个用于从属数据库(用于读取)。 (实际上,这不是一个配置,而是很多配置,所以我有一些母版和从属部件是按重量随机选择的。)
现在,我执行以下操作:在执行查询之前,必须将$ writes设置为true或false。在方法connect()中,适配器根据$ writes的值连接或使用正确的连接。