美文网首页
Yii2:在多个表之间定义关系的正确方法

Yii2:在多个表之间定义关系的正确方法

作者: VE视频引擎 | 来源:发表于2021-05-24 13:44 被阅读0次

在控制器中,我有以下代码:

public function actionView($id)
{
    $query = new Query;
    $query->select('*')
        ->from('table_1 t1')
        ->innerJoin('table_2 t2', 't2.t1_id = t1.id')
        ->innerJoin('table_3 t3', 't2.t3_id = t3.id')
        ->innerJoin('table_4 t4', 't3.t4_id = t4.id')
        ->andWhere('t1.id = ' . $id);
    $rows = $query->all();
    return $this->render('view', [
        'model' => $this->findModel($id),
        'rows' => $rows,
        ]);
}

在视图view.php中显示来自table_2-4的数据,这些数据与table_1相关:

foreach($rows as $row) {
    echo $row['t2_field_1'];
    echo $row['t2_field_2'];
    ...
}

它可以工作,但是我不确定这是否是最正确的Yii2方法.

我试图在模型TableOne中定义关系:

public function getTableTwoRecords()
{
    return $this->hasMany(TableTwo::className(), ['t1_id' => 'id']);
}
public function getTableThreeRecords()
{
    return $this->hasMany(TableThree::className(), ['id' => 't3_id'])
    ->via('tableTwoRecords');
}
public function getTableFourRecords()
{
    return $this->hasMany(TableFour::className(), ['id' => 't4_id'])
    ->via('tableThreeRecords');
}

然后在控制器TableOneController中加入记录:

$records = TableOne::find()
    ->innerJoinWith(['tableTwoRecords'])
    ->innerJoinWith(['tableThreeRecords'])
    ->innerJoinWith(['tableFourRecords'])
    ->all(); 

但是它不起作用.如果我仅加入前三个表,那么它将起作用.如果添加第四张表,则会收到以下错误消息:"获取未知属性:frontend \ models \ TableOne :: t3_id"

如果我以这种方式更改函数getTableFourRecords():

public function getTableFourRecords()
{
    return $this->hasOne(TableThree::className(), ['t4_id' => 'id']);
}

然后我收到此错误消息:"SQLSTATE [42S22]:找不到列:1054'on子句'中的未知列'table_4.t4_id'正在执行的SQL是:SELECT table_1 .* FROM table_1 INNER JOIN table_2 ON table_1 . id = table_2 . t1_id INNER JOIN table_3 ON table_2 . t3_id = table_3 . id INNER JOIN table_4 ON table_1 . id = table_4 . t4_id "

解决方法:

Model TableOne:

public function getTableTwoRecords()
    {
        return $this->hasMany(TableTwo::className(), ['t1_id' => 'id']);
    }

Model TableTwo:

public function getTableThreeRecord()
    {
        return $this->hasOne(TableThree::className(), ['id' => 't3_id']);
    }

Model TableThree:

public function getTableFourRecord()
{
    return $this->hasOne(TableFour::className(), ['id' => 't4_id']);
}

Controller TableOneController:

public function actionView($id)
{
    return $this->render('view', [
         'model' => $this->findModel($id),
    ]);
}

The view table-one/view.php:

foreach ($model->tableTwoRecords as $record) {
    echo ' Table 2 >> ';
    echo ' ID: ' . $record->id;
    echo ' T1 ID: ' . $record->t1_id;
    echo ' T3 ID: ' . $record->t3_id;
    echo ' Table 3 >> ';
    echo ' ID: ' . $record->tableThreeRecord->id;
    echo ' T4 ID: ' . $record->tableThreeRecord->t4_id;
    echo ' Table 4 >> ';
    echo ' ID: ' . $record->tableThreeRecord->tableFourRecord->id;
    echo ' <br>';
}

也可以使用基于GridView的解决方案.

模型TableTwo:

foreach ($model->tableTwoRecords as $record) {
    echo ' Table 2 >> ';
    echo ' ID: ' . $record->id;
    echo ' T1 ID: ' . $record->t1_id;
    echo ' T3 ID: ' . $record->t3_id;
    echo ' Table 3 >> ';
    echo ' ID: ' . $record->tableThreeRecord->id;
    echo ' T4 ID: ' . $record->tableThreeRecord->t4_id;
    echo ' Table 4 >> ';
    echo ' ID: ' . $record->tableThreeRecord->tableFourRecord->id;
    echo ' <br>';
}

使用yii为TableTwo模型生成的TableOneController中的actionView函数已被编辑:

use app\models\TableTwo;
use app\models\TableTwoSearch;
...
public function actionView($id)
{
    $searchModel = new TableTwoSearch([
        't1_id' => $id, // the data have to be filtered by the id of the displayed record
    ]);
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

    return $this->render('view', [
         'model' => $this->findModel($id),
         'searchModel' => $searchModel,
         'dataProvider' => $dataProvider,
    ]);
}

以及views/table-one/view.php的代码如下:

echo GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
     'id',
     't1_id',
     'tableOneRecord.id',
     't3_id',
     'tableThreeRecord.id',
     'tableThreeRecord.t4_id',
     'tableFourRecord.id',
    ],
]);

相关文章

  • Yii2:在多个表之间定义关系的正确方法

    在控制器中,我有以下代码: 在视图view.php中显示来自table_2-4的数据,这些数据与table_1相关...

  • 方法

    方法重载 指同一个类中定义的多个方法之间的关系,满足下列条件的多个方法相互构成重载 1、多个方法在同一个类中 2、...

  • 关系型数据库的几种设计范式(1NF 2NF 3NF BCNF 4

    关系型数据库可以看做“有多个表,表内的数据之间、表与表之间存在关系”的数据库,每个表都由行列组成,列又称作字段、域...

  • 【Java中级】9.0 SSH之Hibernate框架(六)——

    1.0 数据库表与表之间的关系 数据库表与表之间的关系 1.1 一对多关系 什么样关系属于一对多?一个部门对应多个...

  • thinkphp中join用法

    JOIN方法也是连贯操作方法之一,用于根据两个或多个表中的列之间的关系,从这些表中查询数据。 附上项目中的left...

  • 第5关《从零学会SQL:多表查询》练习题答案

    复仇者联盟中多个人物之间有着关系,同样的,表和表之间也会有关系,这种关系在数据库里叫做联结(join),多表查找也...

  • Models and databases 之二 关系

    在关系数据库中设置表与表之间的关系 Many-to-one的关系 定义一个多对一的关系,用django.db.mo...

  • 内外连接 2018-05-04

    什么是连接查询: 根据两个表或多个表的列之间的关系,从这些表中查询数据。 目的:实现多个表查询操作。 语句: FR...

  • Hibernate的多表操作

    以前我们都是通过sql语句连关联两个或多个表。 表之间的关系(实体之间的关系): 一对一 一对多 在多的一方创建指...

  • 数据库建表

    1.如何建表 了解第三范式 能够正确认识表之间的关系:一对一、一对多、多对对 通过主键外键确定表与表之间的关系

网友评论

      本文标题:Yii2:在多个表之间定义关系的正确方法

      本文链接:https://www.haomeiwen.com/subject/lyjxsltx.html