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 相关文章推荐
PHP定时执行计划任务的多种方法小结
Dec 19 PHP
php制作中间带自己定义图片二维码的方法
Jan 27 PHP
php循环创建目录示例分享(php创建多级目录)
Mar 04 PHP
php实现在服务器上创建目录的方法
Mar 16 PHP
PHP版本如何选择?应该使用哪个版本?
May 13 PHP
实例详解PHP中html word 互转的方法
Jan 28 PHP
thinkPHP3.2简单实现文件上传的方法
May 16 PHP
[原创]php简单防盗链验证实现方法
Jul 09 PHP
详解PHP安装mysql.so扩展的方法
Dec 31 PHP
ThinkPHP框架实现数据增删改
May 07 PHP
thinkphp 中的volist标签在ajax操作中的特殊性(推荐)
Jan 15 PHP
tp5框架使用composer实现日志记录功能示例
Jan 10 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使用curl和正则表达式抓取网页数据示例
2014/04/13 PHP
php数组中包含中文的排序方法
2014/06/03 PHP
php 三大特点:封装,继承,多态
2017/02/19 PHP
为javascript添加String.Format方法
2020/08/11 Javascript
基于JQuery的访问WebService的代码(可访问Java[Xfire])
2010/11/19 Javascript
js比较和逻辑运算符的介绍
2013/03/10 Javascript
html文件中jquery与velocity变量中的$冲突的解决方法
2013/11/01 Javascript
javascript中验证大写字母、数字和中文
2014/01/15 Javascript
动态的绑定事件addEventListener方法的使用
2014/01/24 Javascript
JavaScript利用正则表达式去除日期中的-
2014/06/09 Javascript
jQuery的deferred对象详解
2014/11/12 Javascript
js运动动画的八个知识点
2015/03/12 Javascript
Javascript数据结构与算法之列表详解
2015/03/12 Javascript
javascript中基本类型和引用类型的区别分析
2015/05/12 Javascript
JS提交form表单实例分析
2015/12/10 Javascript
Jquery和angularjs获取check框选中的值的方法汇总
2016/01/17 Javascript
基于javascript制作微博发布栏效果
2016/04/04 Javascript
网站发布后Bootstrap框架引用woff字体无法正常显示的解决方法
2016/11/24 Javascript
Jquery Easyui选项卡组件Tab使用详解(10)
2016/12/18 Javascript
AngularJS入门教程二:在路由中传递参数的方法分析
2017/05/27 Javascript
Vue2.0实现将页面中表格数据导出excel的实例
2017/08/09 Javascript
使用vs code开发Nodejs程序的使用方法
2017/09/21 NodeJs
vue ssr 指南详读
2018/06/29 Javascript
React Native基础入门之调试React Native应用的一小步
2018/07/02 Javascript
深入理解JavaScript 箭头函数
2019/05/30 Javascript
Python新手实现2048小游戏
2015/03/31 Python
Python requests库用法实例详解
2018/08/14 Python
Opencv+Python 色彩通道拆分及合并的示例
2018/12/08 Python
Python接口自动化判断元素原理解析
2020/02/24 Python
python中requests模拟登录的三种方式(携带cookie/session进行请求网站)
2020/11/17 Python
.NET remoting中对象激活的两种方式
2015/06/08 面试题
移风易俗倡议书
2014/04/15 职场文书
2015年上半年计生工作总结
2015/03/30 职场文书
2015年物业管理工作总结
2015/04/23 职场文书
goland 清除所有的默认设置操作
2021/04/28 Golang
小程序wx.getUserProfile接口的具体使用
2021/06/02 Javascript