如何在Yii2.0中利用AR联表实现查询功能
在Yii2.0中利用AR(Active Record)联表实现查询功能主要是利用AR对象在数据库中的关联关系。关联关系可以分为一对一、一对多、多对一和多对多。在关联过程中,可以使用Yii2.0提供的关联查询语法,简化了查询的编写工作。
一、创建表结构
在实现联表查询功能之前,我们首先要创建多个表结构,以便使用Yii2.0提供的AR对象进行关联操作。
例如:
首先是user表结构:
CREATE TABLE user (
id int(11) NOT NULL AUTO_INCREMENT,
username varchar(255) NOT NULL,
email varchar(255) NOT NULL,
password_hash varchar(255) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
主键为id,其余字段分别为用户名,电子邮箱和密码哈希值。
接着是article表结构:
CREATE TABLE article (
id int(11) NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL,
content text NOT NULL,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
author_id int(11) NOT NULL,
PRIMARY KEY (id),
KEY FK_article_author (author_id),
CONSTRAINT FK_article_author FOREIGN KEY (author_id) REFERENCES user (id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
主键为id,其余字段分别为文章标题,文章内容,创建时间,更新时间和作者id。其中的author_id是外键,关联了user表中的id字段。
二、建立AR对象
在Yii2.0中,每一个数据表都对应一个AR对象,我们需要建立对应的AR对象以便实现联表查询功能。
例如:
首先是User模型类:
namespace app\models;
use yii\db\ActiveRecord;
class User extends ActiveRecord
{
public static function tableName()
{
return 'user';
}
public function getArticles()
{
return $this->hasMany(Article::className(), ['author_id' => 'id']);
}
}
在这个类中,我们继承了Yii2.0提供的AR类ActiveRecord,并重写了tableName函数,用于指定数据表名。除此之外,我们还定义了一个getArticles函数,用于获取用户所写的文章列表。这个函数使用了Yii2.0提供的hasMany函数,表示一个用户可以对应多篇文章,箭头左边的参数为用户表中的外键id,箭头右边的参数为文章表名。
接下来是Article模型类:
namespace app\models;
use yii\db\ActiveRecord;
class Article extends ActiveRecord
{
public static function tableName()
{
return 'article';
}
public function getAuthor()
{
return $this->hasOne(User::className(), ['id' => 'author_id']);
}
}
在这个类中,我们同样继承了Yii2.0提供的AR类ActiveRecord,并重写了tableName函数,用于指定数据表名。除此之外,我们还定义了一个getAuthor函数,用于获取一篇文章的作者信息。这个函数使用了Yii2.0提供的hasOne函数,表示一篇文章只能对应一个作者,箭头左边的参数为作者表名,箭头右边的参数为文章表中的外键author_id。
三、关联查询
当我们完成了AR类的建立之后,就可以利用Yii2.0提供的关联查询语法进行联表查询。关联查询语法可以分为三种:with、joinWith和andWhere。
with函数:通过with函数实现关联查询
例如:
$users = User::find()
->with('articles')
->all();
这段代码表示查询用户列表,并预先加载用户所写的文章列表。其中with函数的参数为AR类中定义的关联方法名。
joinWith函数:通过joinWith函数实现关联查询并支持连贯操作(例如排序、过滤等)
例如:
$articles = Article::find()
->joinWith('author')
->orderBy('created_at DESC')
->all();
这段代码表示查询文章列表,并关联查询出文章的作者信息。其中joinWith函数的参数同样为AR类中定义的关联方法名,并使用了orderBy函数进行文章按时间倒序排序的操作。
andWhere函数:通过andWhere函数进行逐步过滤筛选
例如:
$articles = Article::find()
->joinWith('author')
->andWhere(['like', 'username', 'test'])
->andWhere(['>', 'created_at', '2021-01-01'])
->all();
这段代码表示查询文章列表,并关联查询出文章的作者信息。利用andWhere函数逐步过滤筛选,查找作者用户名含有“test”并且发表时间在2021年1月1日以后的文章列表。
如果需要展示某个用户的文章列表,可以这样实现:
$articles = Article::find()
->joinWith('author')
->where(['=', 'author_id', $userID])
->orderBy('created_at DESC')
->all();
其中$userID为某个用户的id,可以通过user表查询得到。
通过以上三种方式的灵活组合,我们可以实现复杂的联表查询功能,快速定位数据筛选需求。
