是否可以在实体中定义虚拟字段(SQL 函数调用)?
Is it possible to define virtual fields (SQL function calls) in entities?
是他们的方式,我们可以在Entity中添加MySQL自定义函数
protected $_virtual = ['check_tenant' => '(check_tenant(Tenants.id))'];
我想用 find()
方法调用以下查询
//SELECT id, first_name, check_tenant(Tenants.id) FROM tenants AS Tenants
$this->Tenants->find()->all();
如果我可以在虚拟字段中定义自定义 MySQL 函数,那么它会自动在结果集中 return
我可以在 select()
方法中传递新字段
$this->Tenants->find()
->select(['id', 'check_tenant' => '(check_tenant(Tenants.id))'])->all();
但我想全局定义,所以新字段不需要在每个 find
调用中传递
CakePHP 3.x 中的虚拟 properties 与 Cake[=] 中的虚拟 fields 不同57=] 2.x,后者用于 SQL 查询,前者用于 PHP 级别,通常数据已经存在于实体中。
如果您希望自定义字段出现在 所有 查询中,那么您可以使用 Model.beforeFind()
事件相应地修改查询:
// in TenantsTable class
public function beforeFind(\Cake\Event\Event $event, \Cake\ORM\Query $query, array $options)
{
return $query
// select custom fields (functions builder usage not required, but advised)
->select(function (\Cake\ORM\Query $query) {
return ['check_tenant' => $query->func()->check_tenant([
'Tenants.id' => 'identifier'
])];
})
// ensure that the tables default fields are being selected too
->enableAutoFields(true); // autoFields() before CakePHP 3.4
}
另一个侵入性较小的选项是自定义查找器,您可以在需要的地方明确使用它们:
// in TenantsTable class
public function findWithTenantCheck(\Cake\ORM\Query $query, array $options)
{
return $query
->select(/* ... */)
->enableAutoFields(true);
}
// query data
$query = $this->Tenants->find('withTenantCheck');
另见
- Cookbook > Database Access & ORM > Table Objects > Lifecycle Callbacks > beforeFind
- Cookbook > Database Access & ORM > Entities > Creating Virtual Properties
- Cookbook > Database Access & ORM > Retrieving Data & Results Sets > Using Finders to Load Data
- Cookbook > Database Access & ORM > Retrieving Data & Results Sets > Custom Finder Methods
- Cookbook > Database Access & ORM > Query Builder > Using SQL Functions
是他们的方式,我们可以在Entity中添加MySQL自定义函数
protected $_virtual = ['check_tenant' => '(check_tenant(Tenants.id))'];
我想用 find()
方法调用以下查询
//SELECT id, first_name, check_tenant(Tenants.id) FROM tenants AS Tenants
$this->Tenants->find()->all();
如果我可以在虚拟字段中定义自定义 MySQL 函数,那么它会自动在结果集中 return
我可以在 select()
方法中传递新字段
$this->Tenants->find()
->select(['id', 'check_tenant' => '(check_tenant(Tenants.id))'])->all();
但我想全局定义,所以新字段不需要在每个 find
调用中传递
CakePHP 3.x 中的虚拟 properties 与 Cake[=] 中的虚拟 fields 不同57=] 2.x,后者用于 SQL 查询,前者用于 PHP 级别,通常数据已经存在于实体中。
如果您希望自定义字段出现在 所有 查询中,那么您可以使用 Model.beforeFind()
事件相应地修改查询:
// in TenantsTable class
public function beforeFind(\Cake\Event\Event $event, \Cake\ORM\Query $query, array $options)
{
return $query
// select custom fields (functions builder usage not required, but advised)
->select(function (\Cake\ORM\Query $query) {
return ['check_tenant' => $query->func()->check_tenant([
'Tenants.id' => 'identifier'
])];
})
// ensure that the tables default fields are being selected too
->enableAutoFields(true); // autoFields() before CakePHP 3.4
}
另一个侵入性较小的选项是自定义查找器,您可以在需要的地方明确使用它们:
// in TenantsTable class
public function findWithTenantCheck(\Cake\ORM\Query $query, array $options)
{
return $query
->select(/* ... */)
->enableAutoFields(true);
}
// query data
$query = $this->Tenants->find('withTenantCheck');
另见
- Cookbook > Database Access & ORM > Table Objects > Lifecycle Callbacks > beforeFind
- Cookbook > Database Access & ORM > Entities > Creating Virtual Properties
- Cookbook > Database Access & ORM > Retrieving Data & Results Sets > Using Finders to Load Data
- Cookbook > Database Access & ORM > Retrieving Data & Results Sets > Custom Finder Methods
- Cookbook > Database Access & ORM > Query Builder > Using SQL Functions