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 相关文章推荐
解决MySQL中文输出变成问号的问题
Jun 05 PHP
php 防止单引号,双引号在接受页面转义
Jul 10 PHP
php面向对象全攻略 (十二) 抽象方法和抽象类
Sep 30 PHP
php抓取页面的几种方法详解
Jun 17 PHP
web server使用php生成web页面的三种方法总结
Oct 28 PHP
PHP中Array相关函数简介
Jul 03 PHP
PHP识别二维码的方法(php-zbarcode安装与使用)
Jul 07 PHP
使用一个for循环将N*N的二维数组的所有值置1实现方法
May 29 PHP
php下载远程大文件(获取远程文件大小)的实例
Jun 17 PHP
PHP实现求两个字符串最长公共子串的方法示例
Nov 17 PHP
php闭包中使用use声明变量的作用域实例分析
Aug 09 PHP
PHP如何防止用户重复提交表单
Dec 09 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设计模式之组合模式定义与应用示例
2020/02/01 PHP
PHP filter_var() 函数, 验证判断EMAIL,URL等
2021/03/09 PHP
javascript 跨浏览器开发经验总结(五) js 事件
2010/05/19 Javascript
jQuery EasyUI API 中文文档 - EasyLoader 加载器
2011/09/29 Javascript
jQuery实现移动端滑块拖动选择数字效果
2015/12/24 Javascript
Javascript类型系统之String字符串类型详解
2016/06/21 Javascript
微信小程序 教程之注册页面
2016/10/17 Javascript
Web前端开发之水印、图片验证码
2016/11/27 Javascript
Easyui笔记2:实现datagrid多行删除的示例代码
2017/01/14 Javascript
jQuery 利用ztree实现树形表格的实例代码
2017/09/27 jQuery
JavaScript同源策略和跨域访问实例详解
2018/04/03 Javascript
JS实现的base64加密解密操作示例
2018/04/18 Javascript
基于Vue的延迟加载插件vue-view-lazy
2018/05/21 Javascript
node app 打包工具pkg的具体使用
2019/01/17 Javascript
JS代码优化的8点建议
2020/02/04 Javascript
python根据经纬度计算距离示例
2014/02/16 Python
Python中unittest模块做UT(单元测试)使用实例
2015/06/12 Python
python常用知识梳理(必看篇)
2017/03/23 Python
Mac 上切换Python多版本
2017/06/17 Python
python实现弹窗祝福效果
2019/04/07 Python
利用 PyCharm 实现本地代码和远端的实时同步功能
2020/03/23 Python
CSS3 实用技巧:实现黑白图像效果示例代码
2013/07/11 HTML / CSS
HTML5页面无缝闪开的问题及解决方案
2020/06/11 HTML / CSS
海淘母婴商城:国际妈咪
2016/07/23 全球购物
英国曼彻斯特宠物用品品牌:Bunty Pet Products
2019/07/27 全球购物
亚马逊加拿大网站:Amazon.ca
2020/01/06 全球购物
New Balance比利时官方网站:购买鞋子和服装
2021/01/15 全球购物
课堂教学改革实施方案
2014/03/17 职场文书
董事长助理工作职责
2014/06/08 职场文书
2014迎国庆标语大全
2014/09/19 职场文书
家庭贫困证明
2014/09/23 职场文书
个人向公司借款协议书
2014/10/09 职场文书
SqlServer: 如何更改表的文件组?(进而改变存储位置)
2021/04/05 SQL Server
Python 流媒体播放器的实现(基于VLC)
2021/04/28 Python
python pygame入门教程
2021/06/01 Python
JS实现九宫格拼图游戏
2022/06/28 Javascript