我想创建一个基于云的应用程序,我将应用程序ID和branch_id
存储在会话中,并且我想将application_id
和branch_id
添加到每个数据库查询中。
我很容易使用
覆盖find()
public static function find()
{
return parent::find()->where([]);
}
但问题是我如何覆盖这样的查询
$total_return_price = (new Query())
->select('SUM(product_order.order_price * product_order.quantity) as return_price')
->from('order')
->innerJoin('product_order', 'product_order.order_id = order.id')
->where(['=', 'order.user_id', $user_id])
->andWhere(['=', 'order.status', '4'])
->one();
答案 0 :(得分:2)
一种方法是扩展Query
类并覆盖特征where()
from()
和select()
,并将命名空间从yii\db\Query
更改为{{ 1}}在您希望添加条件的模型中总体而言。但请记住,您有责任确保所有这些表格在表格中包含这两个字段(common\components\Query
和application_id
),您可以将branch_id
替换为yii\db\Query
。< / p>
为什么要覆盖common\components\Query
where()
和from()
?您可以使用以下格式编写查询。
我们假设我们有select()
表格,其中包含字段product
和id
,现在请考虑以下查询。
name
以上将生成以下SQL查询
$q->from ( '{{product}}' )
->all ();
$q->select ( '*' )
->from ( '{{product}}' )
->all ();
$q->from ( '{{product}}' )
->where ( [ 'name' => '' ] )
->all ();
$q->from ( '{{product}}' )
->andWhere ( [ 'name' => '' ] )
->all ();
$q->select ( '*' )
->from ( '{{product}}' )
->where ( [ 'IN' , 'id' , [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 89 , 0 ] ] )
->andwhere ( [ 'name' => '' ] )
->all ();
$q->select ( '*' )
->from ( '{{product}}' )
->where ( [ 'and' ,
[ 'IN' , 'id' , [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 89 , 0 ] ] ,
[ 'name' => '' ]
] )
->all();
因此,您需要在默认情况下将两个条件添加到上面的所有条件
在 SELECT * FROM `product`
SELECT * FROM `product`
SELECT * FROM `product` WHERE (`name`='')
SELECT * FROM `product` WHERE (`name`='')
SELECT * FROM `product` WHERE (`id` IN (1, 2, 3, 4, 5, 6, 7, 89, 0)) AND (`name`='')
SELECT * FROM `product` WHERE (`id` IN (1, 2, 3, 4, 5, 6, 7, 89, 0)) AND (`name`='')
中创建文件名Query
并添加以下内容,
注意:我已为列添加了硬编码值的条件 像这样
common/components
替换 它们与实际使用前的会话中的相应变量一起使用 它用于测试目的,你可以保持原样。我假设你想要上述两个 要在查询中添加[ 'application_id' => 1 ] , [ 'branch_id' => 1 ]
条件的字段。
and
现在测试它会在<?php
namespace common\components;
use yii\db\Query as BaseQuery;
class Query extends BaseQuery {
/**
*
* @param type $condition
* @param type $params
* @return $this
*/
public function where( $condition , $params = array() ) {
parent::where ( $condition , $params );
$defaultConditionEmpty = !isset ( $this->where[$this->from[0] . '.company_id'] );
if ( $defaultConditionEmpty ) {
if ( is_array ( $this->where ) && isset ( $this->where[0] ) && strcasecmp ( $this->where[0] , 'and' ) === 0 ) {
$this->where = array_merge ( $this->where , [ [ $this->from[0] . '.company_id' => 1 ] , [ $this->from[0] . '.branch_id' => 1 ] ] );
} else {
$this->where = [ 'and' , $this->where , [ $this->from[0] . '.company_id' => 1 ] , [ $this->from[0] . '.branch_id' => 1 ] ];
}
}
return $this;
}
/**
*
* @param type $tables
* @return $this
*/
public function from( $tables ) {
parent::from ( $tables );
$this->addDefaultWhereCondition ();
return $this;
}
/**
* Private method to add the default where clause
*/
private function addDefaultWhereCondition() {
if ( $this->from !== null ) {
$this->where = [ 'and' ,
[ $this->from[0] . '.company_id' => 1 ] , [ $this->from[0] . '.branch_id' => 1 ]
];
}
}
}
内部创建一个测试操作,如下所示
SiteController
不要担心我们需要检查生成的查询的public function actionTest() {
$q = new \common\components\Query();
echo $q->from ( '{{product}}' )->createCommand ()->rawSql;
echo "<br>";
echo $q->select ( '*' )->from ( '{{product}}' )->createCommand ()->rawSql;
echo "<br/>";
echo $q->from ( '{{product}}' )->where ( [ 'name' => '' ] )->createCommand ()->rawSql;
echo "<br>";
echo $q->from ( '{{product}}' )->andWhere ( [ 'name' => '' ] )->createCommand ()->rawSql;
echo "<br>";
echo $q->select ( '*' )->from ( '{{product}}' )->where ( [ 'IN' , 'id' , [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 89 , 0 ] ] )->andwhere ( [ 'name' => '' ] )->createCommand ()->rawSql;
echo "<br />";
echo $q->select ( '*' )->from ( '{{product}}' )
->where ( [ 'and' ,
[ 'IN' , 'id' , [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 89 , 0 ] ] ,
[ 'name' => '' ]
] )
->createCommand ()->rawSql;
return;
}
表,因此我们不会使用product
来执行查询来打印构建的查询。因此,访问上述操作时,它现在应该打印查询,并添加如下所示的列
->createCommand()->rawSql
希望能帮助您或其他人寻找相同的解决方案
修改强>
我更新了上面的类,并使用连接添加了对查询的修复,这会引发错误
专栏&#39; company_id&#39; in where子句不明确
我添加了SELECT * FROM `product` WHERE (`application_id`=1) AND (`branch_id`=1)
SELECT * FROM `product` WHERE (`application_id`=1) AND (`branch_id`=1)
SELECT * FROM `product` WHERE (`name`='') AND (`application_id`=1) AND (`branch_id`=1)
SELECT * FROM `product` WHERE (`application_id`=1) AND (`branch_id`=1) AND (`name`='')
SELECT * FROM `product` WHERE (`id` IN (1, 2, 3, 4, 5, 6, 7, 89, 0)) AND (`application_id`=1) AND (`branch_id`=1) AND (`name`='')
SELECT * FROM `product` WHERE (`id` IN (1, 2, 3, 4, 5, 6, 7, 89, 0)) AND (`name`='') AND (`application_id`=1) AND (`branch_id`=1)
数组中可用的第一个table
名称,因为所有表都有字段名称,并且添加第一个选定表的条件将起作用,因为它将与下一个表连接具有from
条件的表格。
我已经从班级中删除了ON
特质覆盖,因为我们不需要它。