簡體   English   中英

CakePHP 3.0-在實體中使用MySQL函數

[英]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()回調內部完成。

為什么需要NOW()vs phps date()?

同樣,使用PHP的函數生成日期也不是一種選擇。 它必須在MySQL服務器上完成。

為什么? 我沒有理由不這樣做。 時區設置不同還是什么? 性能? 如果您有大量寫入操作,則NOW()可能會更慢 好吧,只要使您的phps默認時區匹配數據庫正在使用的內容即可? 然后,您可以簡單地使用Timestamp行為 我很高興學習一些不使用NOW()與使用date()的含義的新知識,但到目前為止,我認為絕對不需要使用NOW()。

在CakePHP 3 ORM中使用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_onupdated_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服務器的時間,而不是數據庫。 但這將與同一表上createdmodified字段一致。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM