php - Yii2中如何实现join查询
问题描述
我已经阅读了所有 Yii2 框架文档,但是在尝试实现它时会感到困惑。
我有一个客户视图,它显示了客户表中的所有字段,包括address_id
地址表中的字段。
我想在 Yii2 框架中使用 MySQL 实现连接查询,但生成的代码如下:
模型中的 CustomerSearch:
class CustomerSearch extends Customer{
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['customer_id', 'store_id', 'address_id', 'active'], 'integer'],
[['first_name', 'last_name', 'email', 'create_date', 'last_update'], 'safe'],
];
}
/**
* {@inheritdoc}
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* @param array $params
*
* @return ActiveDataProvider
*/
public function search($params)
{
$query = Customer::find();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'customer_id' => $this->customer_id,
'store_id' => $this->store_id,
'address_id' => $this->address_id,
'active' => $this->active,
'create_date' => $this->create_date,
'last_update' => $this->last_update,
]);
$query->andFilterWhere(['like', 'first_name', $this->first_name])
->andFilterWhere(['like', 'last_name', $this->last_name])
->andFilterWhere(['like', 'email', $this->email]);
return $dataProvider;
}
客户等级:
class Customer extends \yii\db\ActiveRecord{
/**
* {@inheritdoc}
*/
public static function tableName()
{
return 'customer';
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['store_id', 'first_name', 'last_name', 'address_id'], 'required'],
[['store_id', 'address_id', 'active'], 'integer'],
[['create_date', 'last_update'], 'safe'],
[['first_name', 'last_name'], 'string', 'max' => 45],
[['email'], 'string', 'max' => 50],
];
}
/**
* {@inheritdoc}
*/
public function attributeLabels()
{
return [
'customer_id' => 'Customer ID',
'store_id' => 'Store ID',
'first_name' => 'First Name',
'last_name' => 'Last Name',
'email' => 'Email',
'address_id' => 'Address ID',
'active' => 'Active',
'create_date' => 'Create Date',
'last_update' => 'Last Update',
];
}
}
解决方案
您需要在 ActiveRecord 模型中声明一些关系...
请参阅官方文档中的“使用关系数据”
如果您将其存储address_id
在您的customer
表中,那么您将被绑定到每个拥有 1 单的客户address
(即一对一的关系),这是一个相当糟糕的设计。或者您可以使用联结表。您最好将 存储customer_id
在每个地址记录中并定义一对多关系,使每个客户能够存储多个地址(更像是在现实生活中,即家庭、工作地址等)。
例如,在您的Customer
模型中,您将为has-many
客户地址定义一个关系:
use app\models\Address;
class Customer extends \yii\db\ActiveRecord
{
/**
* {@inheritdoc}
*/
public static function tableName()
{
return 'customer';
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['store_id', 'first_name', 'last_name', 'primary_address_id'], 'required'],
[['store_id', 'primary_address_id', 'active'], 'integer'],
[['create_date', 'last_update'], 'safe'],
[['first_name', 'last_name'], 'string', 'max' => 45],
[['email'], 'string', 'max' => 50],
];
}
/**
* {@inheritdoc}
*/
public function attributeLabels()
{
return [
'customer_id' => 'Customer ID',
'store_id' => 'Store ID',
'first_name' => 'First Name',
'last_name' => 'Last Name',
'email' => 'Email',
'primary_address_id' => 'Primary Address ID',
'active' => 'Active',
'create_date' => 'Create Date',
'last_update' => 'Last Update',
];
}
/**
* @return \yii\db\ActiveQuery
*/
public function getAddresses()
{
return $this->hasMany(Address::className(), ['customer_id' => 'id']);
}
}
在您的Address
模型中,您将has-one
定义反比关系:
/**
* @return \yii\db\ActiveQuery
*/
public function getCustomer()
{
return $this->hasOne(Customer::className(), ['id' => 'customer_id']);
}
然后,您可以通过定义的关系名称访问模型实例中的关系数据,例如:
// SELECT * FROM `customer` WHERE `id` = 123
$customer = Customer::findOne(123);
// SELECT * FROM `address` WHERE `customer_id` = 123
// $addresses is an array of Address objects
$addresses = $customer->addresses;
另请注意,如果您在模式中定义了正确的主键/外键,Gii 模型/CRUD 生成器将自动在您的模型和 CRUD 文件中创建样板关系代码。
推荐阅读
- python-3.x - 无法使用硒(python)在网页上单击打印(图像元素)
- javascript - 如何制作单页导航?没有滚动,只是一个带有自己身体的导航
- javascript - SyntaxError:位置 0 处的 JSON 中的意外令牌 u(Ropsten 测试网)
- python - Python URLencoding 特定结果
- django - 有什么方法可以请求从 Angular 应用程序到 django 的客户端区域基础数据检索?
- windows - 在 Vim 中使用 Yank 复制到 Windows 10 上的剪贴板
- javascript - 失败的 Axios 获取请求的控制台日志原始数据
- ios - 为什么没有要编译的架构 (ONLY_ACTIVE_ARCH=YES, active arch=arm64, VALID_ARCHS=)
- ios - 如何修复错误:“线程 1:EXC_BAD_ACCESS(代码=2,地址=0x7ffee0761ed8)”
- php - 来自 Docker 容器的 SSH 隧道