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 相关文章推荐
网站当前的在线人数
Oct 09 PHP
实用函数9
Nov 08 PHP
php设计模式 Mediator (中介者模式)
Jun 26 PHP
支持中文的php加密解密类代码
Nov 27 PHP
php截取后台登陆密码的代码
May 05 PHP
php安全开发 添加随机字符串验证,防止伪造跨站请求
Feb 14 PHP
PHP 数组和字符串互相转换实现方法
Mar 26 PHP
php实现的DateDiff和DateAdd时间函数代码分享
Aug 16 PHP
php使用fputcsv()函数csv文件读写数据的方法
Jan 06 PHP
浅谈json_encode用法
Mar 05 PHP
safari下载文件自动加了html后缀问题
Nov 09 PHP
PHP实现通过文本文件统计页面访问量功能示例
Feb 13 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,不用COM,生成excel文件
2006/10/09 PHP
关于PHP中字符串与多进制转换函数的实例代码
2016/11/03 PHP
使用JQuery和CSS模拟超链接的用户单击事件的实现代码
2012/05/23 Javascript
onclick与listeners的执行先后问题详细解剖
2013/01/07 Javascript
A标签中通过href和onclick传递的this对象实现思路
2013/04/19 Javascript
JavaScript面向对象编程入门教程
2014/04/16 Javascript
关于javaScript注册click事件传递参数的不成功问题
2014/07/18 Javascript
js使用正则实现ReplaceAll全部替换的方法
2014/07/18 Javascript
javascript中bind函数的作用实例介绍
2014/09/28 Javascript
JavaScript实现简单图片翻转的方法
2015/04/17 Javascript
javascript中createElement的两种创建方式
2015/05/14 Javascript
浅谈javascript中的事件冒泡和事件捕获
2016/12/28 Javascript
vue-router 源码实现前端路由的两种方式
2018/07/02 Javascript
利用hasOwnProperty给数组去重的面试题分享
2018/11/05 Javascript
微信内置浏览器图片查看器的代码实例
2019/10/08 Javascript
js实现鼠标点击页面弹出自定义文字效果
2019/12/24 Javascript
Vue单文件组件开发实现过程详解
2020/07/30 Javascript
js禁止查看源文件屏蔽Ctrl+u/s、F12、右键等兼容IE火狐chrome
2020/10/01 Javascript
python中List的sort方法指南
2014/09/01 Python
python采用getopt解析命令行输入参数实例
2014/09/30 Python
python中子类调用父类函数的方法示例
2017/08/18 Python
Django 2.0版本的新特性抢先看!
2018/01/05 Python
Python实现求两个数组交集的方法示例
2019/02/23 Python
详解用Python实现自动化监控远程服务器
2019/05/18 Python
Django获取应用下的所有models的例子
2019/08/30 Python
Numpy中np.max的用法及np.maximum区别
2020/11/27 Python
爱淘宝:淘宝网购物分享平台
2017/04/28 全球购物
英国工具中心:UK Tool Centre
2017/07/10 全球购物
英超联赛的首选足球:Mitre足球
2019/05/06 全球购物
100%羊绒:NakedCashmere
2020/08/26 全球购物
报到证丢失证明
2014/01/11 职场文书
高一家长会邀请函
2014/01/12 职场文书
三严三实·严以律己心得体会
2016/01/13 职场文书
Win11 Build 21996.1 Dev版怎么样? win11系统截图欣赏
2021/11/21 数码科技
如何利用python实现列表嵌套字典取值
2022/06/10 Python