Silverstripe - 删除数据对象而不是使用自定义SQL查询的更好方法

时间:2014-03-13 16:55:37

标签: php silverstripe

是否有更好的方法删除早于x-days的数据对象而不是使用自定义SQL查询?

这就是我现在所做的事情

    $host = 'localhost';
    $username = 'db123';
    $password = 'pass';
    $db_name = 'db123';

    mysql_connect("$host", "$username", "$password")or die("cannot connect"); 
    mysql_select_db("$db_name")or die("cannot select DB");

    $sql = "DELETE FROM Cart WHERE Created < (CURDATE() - INTERVAL 1 DAY)";
    $result = mysql_query($sql);

    mysql_close();

1 个答案:

答案 0 :(得分:13)

首先,使用mysql_query 错误,不仅仅是在这种情况下。 mysql_query已被弃用,不应再使用。

其次,SilverStripe已经有一个DB连接,不要尝试创建另一个。 SilverStripe提供了许多查询数据库的方法。


选项1:

最干净的方法当然是使用SilverStripe ORM DataObject有一个名为->delete()的方法 使用delete比编写自己的SQL查询有几个优点。

  • 很容易
  • 它会从你的所有表中删除DataObject(例如,DataObject类FolderFile的子类,所以如果你执行$myFolder->delete()它会删除这个{ {1}}表中的{1}}以及Folder表中的{1}}表(如果有File表))
  • 它将执行SilverStripe删除挂钩(FolderFolder

非常直接:

onBeforeDelete

解决您的问题:

onAfterDelete
但是,当删除许多// to delete all `DataObject`s in a List, just loop it and call ->delete() foreach($list as $item) { $item->delete(); } // there also is a method that does that for you, however, I would advise against it // because it is currently inconsistently implemented and might lead to unexpected results // $list->removeAll(); // i STRONGLY RECOMMEND AGAINST THIS // if $list is a DataList, it will delete all records // if $list is a ManyManyList, it will unlink all records // if $list is a ArrayList, it will error because there is no removeAll() method on ArrayList s:performance时,它也有一个主要的缺点 但是,如果您可以说性能不是一个大问题,我仍然建议使用$date = date('Y-m-d H:i:s', strtotime("now -1 day")); $list = Cart::get()->filter('Created:LessThan', $date); foreach($list as $item) { $item->delete(); } 。好处通常大于缺点。

Datamodel / ORMDataObject

的SilverStripe文档中详细了解DataObject->delete()DataList::get()

选项2:

如果您真的需要,可以使用较低级别的ORM来执行删除:

->filter()

详细了解SilverStripe docs

中的->delete()

选项3:

如果您出于某些原因确实想要完全避免使用ORM,SilverStripe还允许您执行原始SQL查询:

$query = new SQLQuery();
$query->setDelete(true);
$query->setFrom('Cart');
$query->setWhere('Created  < (CURDATE() - INTERVAL 1 DAY)"');
// if you want to debug the query, you can use ->sql() to get it as string
// echo $query->sql();
$query->execute();