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
php实现的MySQL通用查询程序
Mar 11 PHP
6种php上传图片重命名的方法实例
Nov 04 PHP
详解php中反射的应用
Mar 15 PHP
PHP Static延迟静态绑定用法分析
Mar 16 PHP
Laravel SQL语句记录方式(推荐)
May 26 PHP
php reset() 函数指针指向数组中的第一个元素并输出实例代码
Nov 21 PHP
Thinkphp整合微信支付功能
Dec 14 PHP
基于php(Thinkphp)+jquery 实现ajax多选反选不选删除数据功能
Feb 24 PHP
PHP里面把16进制的图片数据显示在html的img标签上(实现方法)
May 02 PHP
php实现的支付宝网页支付功能示例【基于TP5框架】
Sep 16 PHP
Laravel 实现关系模型取出需要的字段
Oct 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 已经成熟
2006/12/04 PHP
php通过COM类调用组件的实现代码
2012/01/11 PHP
linux中cd命令使用详解
2015/01/08 PHP
jquery 经典动画菜单效果代码
2010/01/26 Javascript
不提示直接关闭网页窗口的JS示例代码
2013/12/17 Javascript
一个简单的实现下拉框多选的插件可移植性比较好
2014/05/05 Javascript
Javascript基础教程之while语句
2015/01/18 Javascript
js的for in循环和java里foreach循环的区别分析
2015/01/28 Javascript
JavaScript获取当前网页标题(title)的方法
2015/04/03 Javascript
JS实现下拉菜单赋值到文本框的方法
2015/08/18 Javascript
js实现仿爱微网两级导航菜单效果代码
2015/08/31 Javascript
Javascript 实现微信分享(QQ、朋友圈、分享给朋友)
2016/10/21 Javascript
详解Angular 开发环境搭建
2017/06/22 Javascript
Node.js使用cookie保持登录的方法
2018/05/11 Javascript
从理论角度讨论JavaScript闭包
2019/04/03 Javascript
Nodejs异步流程框架async的方法
2019/06/07 NodeJs
如何在Vue中抽离接口配置文件
2019/10/31 Javascript
Python算法应用实战之栈详解
2017/02/04 Python
Python导入模块时遇到的错误分析
2017/08/30 Python
Python爬取当当、京东、亚马逊图书信息代码实例
2017/12/09 Python
python中的文件打开与关闭操作命令介绍
2018/04/26 Python
python正则表达式之对号入座篇
2018/07/24 Python
python selenium 执行完毕关闭chromedriver进程示例
2019/11/15 Python
NumPy中的维度Axis详解
2019/11/26 Python
Python中低维数组填充高维数组的实现
2019/12/02 Python
浅谈对pytroch中torch.autograd.backward的思考
2019/12/27 Python
python字典通过值反查键的实现(简洁写法)
2020/09/30 Python
Bodum官网:咖啡和茶壶、玻璃器皿、厨房电器等
2018/08/01 全球购物
Halston Heritage官网:简洁的日装,稍显奢华的晚装
2018/11/20 全球购物
Roxy俄罗斯官方网站:冲浪和滑雪板的一切
2020/06/20 全球购物
乡镇党的群众路线教育实践活动总结报告
2014/10/30 职场文书
领导视察通讯稿
2015/07/18 职场文书
新闻报道稿范文
2015/07/23 职场文书
解决SpringBoot跨域的三种方式
2021/06/26 Java/Android
python unittest单元测试的步骤分析
2021/08/02 Python
Go中使用gjson来操作JSON数据的实现
2022/08/14 Golang