[英]CakePHP 3.0 - Using MySQL functions in Entities
我在將MySQL函數與CakePHP數據庫實體一起使用時遇到麻煩。 我在搜索中發現的一些提及僅針對CakePHP的早期版本,不再起作用。
同樣,使用PHP的函數生成日期也不是一種選擇。 它必須在MySQL服務器上完成。
這是我的代碼示例:
$record = [
$this->_table->primarykey() => $id,
"a" => $a,
"b" => $b,
"c" => $c,
"updated_on" => "NOW()"
];
$result = $this->_table->save(new Entity($record));
這將導致數據庫行中的updated_on
字段中的默認日期時間值為0000-00-00 00:00:00
,而不是使用當前時間戳填充該日期時間。
紅利點:如果我想添加一個created_on
字段,我該如何使用實體來處理呢? 如何在第一次插入記錄created_on
不是在每次更新時僅將一次created_on
設置?
一如既往,我非常感謝每一個評論和回答!
首先,我不會做實體內部的任何業務邏輯運算。 特別是不要將代碼放在實體中。 如果您真的認為必須在此執行,則至少調用一個表方法並在其中封裝邏輯。 實體被認為是數據對象, 僅此而已 。 因此,在實體內部執行保存操作會使架構反轉。 這應該在模型的beforeSave()回調內部完成。
同樣,使用PHP的函數生成日期也不是一種選擇。 它必須在MySQL服務器上完成。
為什么? 我沒有理由不這樣做。 時區設置不同還是什么? 性能? 如果您有大量寫入操作,則NOW()可能會更慢 。 好吧,只要使您的phps默認時區匹配數據庫正在使用的內容即可? 然后,您可以簡單地使用Timestamp行為 。 我很高興學習一些不使用NOW()與使用date()的含義的新知識,但到目前為止,我認為絕對不需要使用NOW()。
如果您已閱讀該手冊 ,則可能會看到以下內容:
CakePHP的ORM為一些常用的SQL函數提供了抽象。 使用抽象允許ORM選擇所需功能的平台特定實現。 例如,concat在MySQL,PostgreSQL和SQL Server中的實現方式有所不同。 使用抽象可以使您的代碼具有可移植性:
該文檔還提供了一個示例:
// Results in SELECT COUNT(*) count FROM ...
$query = $articles->find();
$query->select(['count' => $query->func()->count('*')]);
隨后是開箱即用的受支持功能的列表,其中包括:
now()以“時間”或“日期”作為參數,使您可以獲取當前時間或當前日期。
如果您繼續閱讀,它會告訴您
除了上述函數外,func()方法還可用於創建任何通用的SQL函數,例如year,date_format,convert等。例如:
我還沒有必要自己使用now(),但是基於以上信息,我想應該是:
$date = $query->func()->now();
然后,只需將該值保存到數據庫即可。 我認為該框架的單元測試還將顯示一個如何使用它的示例。
紅利點:如果我想添加一個created_on字段,我該如何使用實體來處理呢? 如何在第一次插入記錄時而不是在每次更新時僅將一次created_on設置?
$entity->isNew()
將允許您檢查實體是否為新實體,並采取相應措施。 如果是新的,則設置時間戳記。
您在架構錯誤的位置重新發明了Timestamp行為。 正確或不正確取決於您。
這可能不會完全回答您的“我如何使用MySQL函數”問題,但我可以向您指出總體方向 。
然而。 要在表中設置created_on
和updated_on
日期時間字段,我建議使用Cake提供的功能。 通過使用提供的行為 :
namespace App\Model\Table;
use Cake\ORM\Table;
class ArticlesTable extends Table
{
public function initialize(array $config)
{
$this->addBehavior('Timestamp', [
'events' => [
'Model.beforeSave' => [
'created_on' => 'new',
'updated_on' => 'always'
]
]
]);
}
}
將時間戳記行為添加到實體表中,可以讓Cake的ORM為您處理字段的更新。
這個合理問題的簡單答案是:
use Cake\I18n\Time;
$record = [
$this->_table->primarykey() => $id,
"a" => $a,
"b" => $b,
"c" => $c,
"updated_on" => Time::now()
];
$result = $this->_table->save(new Entity($record));
在now()
這里使用將獲得來自PHP服務器的時間,而不是數據庫。 但這將與同一表上created
和modified
字段一致。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.