所以,让我说我有一个记录:
$record = new Record();
并且假设我将一些数据分配给该记录:
$record->setName("SomeBobJoePerson");
如何将其导入数据库。我是.....
A)让模块做到。
class Record{
public function __construct(DatabaseConnection $database)
{
$this->database = $database;
}
public function setName($name)
{
$this->database->query("query stuff here");
$this->name = $name;
}
}
B)运行脚本末尾的模块
class Record{
private $changed = false;
public function __construct(array $data=array())
{
$this->data = $data;
}
public function setName($name)
{
$this->data['name'] = $name;
$this->changed = true;
}
public function isChanged()
{
return $this->changed;
}
public function toArray()
{
return $this->array;
}
}
class Updater
{
public function update(array $records)
{
foreach($records as $record)
{
if($record->isChanged())
{
$this->updateRecord($record->toArray());
}
}
}
public function updateRecord(){ // updates stuff
}
}
答案 0 :(得分:1)
你可以问你的一个问题是你是否要重新发明轮子。像Propel或Doctrine这样的ORM层已经实现了对象到(R)DBMS映射,因此您可以查看它们的实现细节。
Propel将使用您的第二种方法,他们甚至在字段级别保留标志以创建一个更新语句(这将使数据库交互保持最小)。如果你研究他们的来源,你会学到很多东西(或者更好,不要浪费你的时间并使用他们的实施 - 你不会后悔:p)。
答案 1 :(得分:0)
这取决于您计划如何实施...在单个点(在请求结束时)执行所有写入操作很不错,因为它允许您通过尽可能合并查询来优化操作。但要做到这一点,你必须创建一个类似于UnitOfWork的东西来跟踪删除/更新/插入什么,这可以打开另一个蠕虫。
另一方面,如果你在实体上调用持久性方法时直接执行它,那么你不必担心这一点。
这两种方法都意味着您必须有一些方法来确保您始终拥有对象中的当前数据,但实现所需的工作随着您选择的方式而变得复杂。
答案 2 :(得分:0)
示例A在调用setName
时更新数据库。此函数看起来像一个简单的写访问器,但在调用(连接到数据库,执行查询等)时执行昂贵的操作。这些意想不到的网站效应使得例B更具吸引力。
作为另一个例子:稍后您可能需要一个Validator类来检查Record并确保Record处于有效状态。但是为了检查记录,你必须首先通过设置一个名称来定义它 - 所以记录将被保留,然后才能验证它的状态。 定义对象状态与持久对象状态不同。
数据模型方法可能更好,而不是基于记录的方法。例如:
class Model {
protected $_props= array();
public $changed= false;
static public $models= array();
function __set($name, $value) {
$this->changed= true;
$this->_props[$name]= $value;
}
function __construct() {
Model::$models[]= $this;
}
public function save() {
// Execute database query for saving the current Model
}
static public function update() {
foreach (Model::$models as $model) {
if ($model->changed) {
$model->save();
}
}
}
}
基于模型的解决方案在创建不同的模型类型时确实很有用。例如:
class Person extends Model {
public function save() {
// Execute person-specific write operations
}
}
class Doctor extends Person {
public function save() {
// Execute all Person write operations
parent::save();
// Save the extra bits that belong to a doctor
}
}
$person1= new Person();
$person->firstname= 'Jon';
$person->lastname= 'Skeet';
$doctor1= new Doctor();
$doctor1->firstname= 'House';
$doctor1->lastname= 'MD';
// Save all modified models
Model::update();
虽然我很少使用这种大规模更新机制。写条件通常更具体。