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 三维饼图的实现代码
Sep 28 PHP
10条PHP高级技巧[修正版]
Aug 02 PHP
js限制checkbox勾选的个数以及php获取多个checkbbox的方法深入解析
Jul 18 PHP
通过table标签,PHP输出EXCEL的实现方法
Jul 24 PHP
小谈php正则提取图片地址
Mar 27 PHP
PHP中数组的分组排序实例
Jun 01 PHP
安装ImageMagick出现error while loading shared libraries的解决方法
Sep 23 PHP
以实例全面讲解PHP中多进程编程的相关函数的使用
Aug 18 PHP
Laravel中使用FormRequest进行表单验证方法及问题汇总
Jun 19 PHP
PHP实现上传多文件示例代码
Feb 20 PHP
PHP 布尔值的自增与自减的实现方法
May 03 PHP
php 实现银联商务H5支付的示例代码
Oct 12 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 函数语法介绍一
2009/06/14 PHP
PHP 获取客户端 IP 地址的方法实例代码
2018/11/11 PHP
javascript 读取图片文件的大小
2009/06/25 Javascript
Javascript+XMLHttpRequest+asp.net无刷新读取数据库数据
2009/08/09 Javascript
JS window.opener返回父页面的应用
2009/10/24 Javascript
Js参数值中含有单引号或双引号问题的解决方法
2013/11/06 Javascript
js获取页面description的方法
2015/05/21 Javascript
jQuery实现指定内容滚动同时左侧或其它地方不滚动的方法
2015/08/08 Javascript
jQuery实现垂直半透明手风琴特效代码分享
2015/08/21 Javascript
轻松搞定jQuery.noConflict()
2016/02/15 Javascript
javascript时间排序算法实现活动秒杀倒计时效果
2021/01/28 Javascript
vue双向绑定简要分析
2017/03/23 Javascript
Bootstrap Table使用整理(三)
2017/06/09 Javascript
微信小程序画布圆形进度条显示效果
2020/11/17 Javascript
JS使用Dijkstra算法求解最短路径
2019/01/17 Javascript
vue项目从node8.x升级到12.x后的问题解决
2019/10/25 Javascript
如何搜索查找并解决Django相关的问题
2014/06/30 Python
跟老齐学Python之复习if语句
2014/10/02 Python
Python函数中定义参数的四种方式
2014/11/30 Python
Python+MongoDB自增键值的简单实现
2016/11/04 Python
使用Python横向合并excel文件的实例
2018/12/11 Python
Python 进程之间共享数据(全局变量)的方法
2019/07/16 Python
python 导入数据及作图的实现
2019/12/03 Python
Python测试Kafka集群(pykafka)实例
2019/12/23 Python
python词云库wordCloud使用方法详解(解决中文乱码)
2020/02/17 Python
Python自省及反射原理实例详解
2020/07/06 Python
python装饰器三种装饰模式的简单分析
2020/09/04 Python
Gap中国官网:美式休闲风服饰
2017/02/05 全球购物
英国网上超市:Ocado
2020/03/05 全球购物
中国一家综合的外贸B2C电子商务网站:DealeXtreme(DX)
2020/03/10 全球购物
经济管理专业毕业生推荐信
2013/11/11 职场文书
银行内勤岗位职责
2014/04/09 职场文书
交警个人先进事迹材料
2014/05/11 职场文书
经验交流材料格式
2014/12/30 职场文书
2015双创工作总结
2015/07/24 职场文书
《山中访友》教学反思
2016/02/24 职场文书