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


Posted in PHP onFebruary 10, 2017

背景:在一个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');
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
为php4加入动态flash文件的生成的支持
Oct 09 PHP
PHP 编程请选择正确的文本编辑软件
Dec 21 PHP
解决控件遮挡问题:关于有窗口元素和无窗口元素
Jan 28 PHP
php开发留言板的CRUD(增,删,改,查)操作
Apr 19 PHP
解析smarty 截取字符串函数 truncate的用法介绍
Jun 20 PHP
深入php中var_dump方法的使用详解
Jun 24 PHP
php使用curl发送json格式数据实例
Dec 17 PHP
php中的ini配置原理详解
Oct 14 PHP
初识laravel5
Mar 02 PHP
简单PHP会话(session)说明介绍
Aug 21 PHP
PHP面向对象程序设计之类与反射API详解
Dec 02 PHP
MAC下通过改apache配置文件切换php多版本的方法
Apr 26 PHP
yii2 数据库读写分离配置示例
Feb 10 #PHP
php 基础函数
Feb 10 #PHP
PHP isset()与empty()的使用区别详解
Feb 10 #PHP
PHP获取当前URL路径的处理方法(适用于多条件筛选列表)
Feb 10 #PHP
Thinkphp3.2实用篇之计算型验证码示例
Feb 09 #PHP
PHP 验证身份证是否合法的函数
Feb 09 #PHP
如何打开php的gd2库
Feb 09 #PHP
You might like
PHP生成便于打印的网页
2006/10/09 PHP
PHP下操作Linux消息队列完成进程间通信的方法
2010/07/24 PHP
PHP 简易输出CSV表格文件的方法详解
2013/06/20 PHP
php设计模式之单例模式使用示例
2014/01/20 PHP
PHP格式化MYSQL返回float类型的方法
2016/03/30 PHP
php微信公众号开发之现金红包
2018/04/16 PHP
FF IE兼容性的修改小结
2009/09/02 Javascript
jQuery使用andSelf()来包含之前的选择集
2014/05/19 Javascript
javascript中的throttle和debounce浅析
2014/06/06 Javascript
jQuery操作JSON的CRUD用法实例
2015/02/25 Javascript
浅谈javascript中的constructor
2016/06/08 Javascript
js返回顶部实例分享
2016/12/21 Javascript
JavaScript 字符串数字左补位,右补位,取固定长度,截位扩展函数代码
2017/03/25 Javascript
JavaScript变量作用域_动力节点Java学院整理
2017/06/27 Javascript
js实现前端图片上传即时预览功能
2017/08/02 Javascript
阿里大于短信验证码node koa2的实现代码(最新)
2017/09/07 Javascript
vue中简单弹框dialog的实现方法
2018/02/26 Javascript
js获取form表单中name属性的值
2019/02/27 Javascript
微信小程序移动拖拽视图-movable-view实例详解
2019/08/17 Javascript
python切换hosts文件代码示例
2013/12/31 Python
Python实现的HTTP并发测试完整示例
2020/04/23 Python
十个Python练手的实战项目,学会这些Python就基本没问题了(推荐)
2019/04/26 Python
pytorch中获取模型input/output shape实例
2019/12/30 Python
Python 格式化输出_String Formatting_控制小数点位数的实例详解
2020/02/04 Python
Python3查找列表中重复元素的个数的3种方法详解
2020/02/13 Python
有趣、实用和鼓舞人心的产品:Inspire Uplift
2019/11/05 全球购物
捷克建筑材料网上商店:DEK.cz
2021/03/06 全球购物
优纳科技软件测试面试题
2012/05/15 面试题
小学运动会表扬稿
2014/01/19 职场文书
幼儿园中秋节活动反思
2014/02/16 职场文书
观看《永远的雷锋》心得体会
2014/03/12 职场文书
医疗专业毕业生求职信
2014/08/28 职场文书
2014班子成员自我剖析材料思想汇报
2014/10/01 职场文书
警告通知
2015/04/25 职场文书
《珍珠鸟》教学反思
2016/02/16 职场文书
2016年五一国际劳动节活动总结
2016/04/06 职场文书