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 相关文章推荐
IIS下配置Php+Mysql+zend的图文教程
Dec 08 PHP
用PHP函数解决SQL injection
Dec 09 PHP
MySQL GBK→UTF-8编码转换
May 24 PHP
php实现自动获取生成文章主题关键词功能的深入分析
Jun 03 PHP
探讨PHP中this,self,parent的区别详解
Jun 08 PHP
CI框架自动加载session出现报错的解决办法
Jun 17 PHP
PHP制作百度词典查词采集器
Jan 29 PHP
PHP模板引擎Smarty中的保留变量用法分析
Apr 11 PHP
php面向对象编程self和static的区别
May 08 PHP
实例讲解php实现多线程
Jan 27 PHP
PDO::commit讲解
Jan 27 PHP
php实现JWT(json web token)鉴权实例详解
Nov 05 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
YB217、YB235、YB400浅听
2021/03/02 无线电
Joomla数据库操作之JFactory::getDBO用法
2016/05/05 PHP
兼容IE和FF的图片上传前预览js代码
2013/05/28 Javascript
jquery ajax 简单范例(界面+后台)
2013/11/19 Javascript
编写高效jQuery代码的4个原则和5个技巧
2014/04/24 Javascript
浅谈jquery中delegate()与live()
2015/06/22 Javascript
JavaScript ParseFloat()方法
2015/12/18 Javascript
解析javascript瀑布流原理实现图片滚动加载
2016/03/10 Javascript
浅谈js中的in-for循环
2016/06/28 Javascript
原生js编写基于面向对象的分页组件
2016/12/05 Javascript
基于vue实现swipe分页组件实例
2017/05/25 Javascript
在vue中给列表中的奇数行添加class的实现方法
2018/09/05 Javascript
单页面vue引入百度统计的使用方法示例详解
2018/10/13 Javascript
layer弹窗在键盘按回车将反复刷新的实现方法
2019/09/25 Javascript
vue-router结合vuex实现用户权限控制功能
2019/11/14 Javascript
Vue+elementUI实现多图片上传与回显功能(含回显后继续上传或删除)
2020/03/23 Javascript
使用Python中PDB模块中的命令来调试Python代码的教程
2015/03/30 Python
Python实现的手机号归属地相关信息查询功能示例
2017/06/08 Python
我喜欢你 抖音表白程序python版
2019/04/07 Python
用pycharm开发django项目示例代码
2019/06/13 Python
python中的colorlog库使用详解
2019/07/05 Python
python 将字符串中的数字相加求和的实现
2019/07/18 Python
python 字典 setdefault()和get()方法比较详解
2019/08/07 Python
python函数的作用域及关键字详解
2019/08/20 Python
pandas factorize实现将字符串特征转化为数字特征
2019/12/19 Python
H5最强接口之canvas实现动态图形功能
2019/05/31 HTML / CSS
匡威俄罗斯官网:Converse俄罗斯
2020/05/09 全球购物
一份比较全的PHP面试题
2016/07/29 面试题
网上常见的一份Linux面试题(多项选择部分)
2015/02/07 面试题
教师档案管理制度
2014/01/23 职场文书
不假外出检讨书
2014/01/27 职场文书
护理专业毕业生自我鉴定总结
2014/03/24 职场文书
公安机关正风肃纪剖析材料
2014/10/10 职场文书
Oracle11g R2 安装教程完整版
2021/06/04 Oracle
解决persistence.xml配置文件修改存放路径的问题
2022/02/24 Java/Android
Python简易开发之制作计算器
2022/04/28 Python