将心比心,方得人心~

yii多表关联一对一查询之hasOne

周洲 2017-04-07 10:27:54

多表关联一对一查询之hasOne

public function actionAbout()
{
	$article = Article::findOne(1);
	$category = $article->hasOne('app\models\Category', ['id'=>'cate_id'])->one();
	var_dump($category);
}

上面的例子可以更加简便为:

public function actionAbout()
{
	$article = Article::findOne(1);
	$category = $article->hasOne(Category::className(), ['id'=>'cate_id'])->one();
	var_dump($category);
}

上面的例子hasOne()是直接写在控制器中的,如果需要多次用到此方法,会产生耦合,规范的写法是将此方法方法模型中:

模型中:

class Article extends ActiveRecord {

    public function getCategory()
    {
        $category = $this->hasOne(category::className(), ['id'=>'cate_id'])->one();
        return $category;
    }
    
}

控制器中:

public function actionAbout()
{
	$article = Article::findOne(1);
	$category = $article->getCategory();
	var_dump($category);
}

hasOne()第二种写法:

模型中:

class Article extends ActiveRecord {

    public function getCategory()
    {
        $category = $this->hasOne(category::className(), ['id'=>'cate_id'])->asArray();
        return $category;
    }
}

控制器中:

public function actionAbout()
{
	$article = Article::findOne(1);
	$category = $article->category;
	var_dump($category);
}

PS:通过调用category属性,会自动走__get()魔术函数,__get()会自动补上get,变成getCategory(),并且会自动判断到hasOne()在结尾加上one(),所以模型里不需要加one()也行,最后返回结果。


上面的例子都是获取的一篇文章对应的分类,项目中我们常常都是获取每一篇文章对应的分类:

模型中:

class Article extends ActiveRecord {

    public function getCategory()
    {
        $category = $this->hasOne(category::className(), ['id'=>'cate_id'])->asArray();
        return $category;
    }
}

控制器中:

public function actionAbout()
{
	$articles = Article::find()->all();
	foreach ($articles as $article) {
		$category[] = $article->category;
	}

	var_dump($category);
}

PS:这种方法执行sql次数为下面次数之和:

$articles = Article::find()->all();   //执行1次

foreach ($articles as $article) {
    $category[] = $article->category;  //有多少篇文章执行多少次sql
}


上例性能优化:

模型中:

class Article extends ActiveRecord {

    public function getCategory()
    {
        $category = $this->hasOne(category::className(), ['id'=>'cate_id']);
        return $category;
    }
}

控制器中:

public function actionAbout()
{
	$articles = Article::find()->with('category')->asArray()->all();
	var_dump($articles);
}

PS:这种方法只执行一次sql语句,效率会大大提高。实际是使用了join查询。


打赏

『微信打赏』

Tag标签yii 

我是有底线的