当前位置:首页 > PHP教程 > PHP常见问题

Yii2实现跨mysql数据库关联查询排序功能代码

背景:在一个mysql服务器上(注意:两个数据库必须在同一个mysql服务器上)有两个数据库:

memory (存储常规数据表) 中有一个 user 表(记录用户信息)

memory_stat (存储统计数据表) 中有一个 user_stat (记录用户统计数据)

现在在 user 表生成的 gridview 列表中展示 user_stat 中的统计数据

只需要在user的model类中添加关联

public function getstat() { return $this->hasone(userstat::classname(), ['user_id' => 'id']); }

在gridview就可以这样使用来展示统计数据

<?= gridview::widget([ 'dataprovider' => $dataprovider, 'columns' => [ //其他列 [ 'label' => '统计数据', 'value' => function($model){ return isset($model->stat->data) ? $model->stat->data : null; } ], //其他列 ], ]); ?>

现在增加了一个需求,需要在user gridview 列表中对统计数据进行排序和筛选

若 user 和 user_stat 表在同一个数据库下我们可以这样做:

usersearch:

public $data; public function rules() {/*{{{*/ return [ ['data'], 'integer'], //其他列 ]; }/*}}}*/ public function search($params, $onlyactiveusers = false) { $query = user::find(); $query->joinwith(['stat']); $dataprovider = new activedataprovider([ 'query' => $query, 'sort' => [ 'attributes' => [ //其他列 'data' => [ 'asc' => [userstat::tablename() . '.data' => sort_asc], 'desc' => [userstat::tablename() . '.data' => sort_desc], ], //其他列 ], 'defaultorder' => [ 'id' => sort_desc, ], ], 'pagination' => [ 'pagesize' => 50, ], ]); $this->load($params); if (!$this->validate()) { $query->where('0=1'); return $dataprovider; } $query->filterwhere([ //其他列 userstat::tablename() . '.data' => $this->data ]); return $dataprovider; }

在gridview就可以这样使用来展示统计数据,就可以排序了

<?= gridview::widget([ 'dataprovider' => $dataprovider, 'columns' => [ //其他列 [ 'label' => '统计数据', 'attribute' => 'data', 'value' => function($model){ return isset($model->stat->data) ? $model->stat->data : null; } ], //其他列 ], ]); ?>

search 表单中添加以下列就可以筛选了

<?php $form = activeform::begin(); ?> //其他列 <?= $form->field($model, 'data')?> //其他列 <div class="form-group"> <?= html::submitbutton('search', ['class' => 'btn btn-primary']) ?> </div> <?php activeform::end(); ?>

然而现实是残酷的, user 和 user_stat 表并在同一个数据库下。

于是就会报出这样一个错误:

sqlstate[42s02]: base table or view not found: 1146 table 'memory.user_stat' doesn't exist
the sql being executed was: ...

要在两个数据库(同一台服务器)上进行关联数据查询,纯sql语句如下:

复制代码 代码如下:

select a.*,b.* from memory.user as a,memory_stat.user_stat as b where a.id=b.user_id;

yii2转化成 sql 语句时默认不会在表明前添加数据库名,于是mysql在执行sql语句时就会默认此表在memory数据库下。

复制代码 代码如下:

select a.*,b.* from memory.user as a,memory.user_stat as b where a.id=b.user_id;

于是就出现了以上报错信息。

那么,如何来解决这个问题呢?

其实很简单,只需要重写 user_stat 的 model 类下的 tablename() 方法就可以了。

// 默认是这样的 public static function tablename() { return 'user_stat'; } public static function getdb() { return yii::$app->get('dbstat'); }
// 只需要在表明前添加数据库名 public static function tablename() { return 'memory_stat.user_stat'; } public static function getdb() { return yii::$app->get('dbstat'); }
// 为了提高代码稳定性,可以这样写 public static function tablename() { preg_match("/dbname=([^;]+)/i", static::getdb()->dsn, $matches); return $matches[1].'.user_stat'; } public static function getdb() { return yii::$app->get('dbstat'); }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持硕编程。



【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!