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 相关文章推荐
利用curl抓取远程页面内容的示例代码
Jul 23 PHP
php cookie使用方法学习笔记分享
Nov 07 PHP
php使用filter过滤器验证邮箱 ipv6地址 url验证
Dec 25 PHP
PHP 登录完成后如何跳转上一访问页面
Jan 14 PHP
PHP Curl出现403错误的解决办法
May 29 PHP
推荐十款免费 WordPress 插件
Mar 24 PHP
WordPress中用于获取文章作者与分类信息的方法整理
Dec 17 PHP
PHP+MySql+jQuery实现的&quot;顶&quot;和&quot;踩&quot;投票功能
May 21 PHP
php实现通过soap调用.Net的WebService asmx文件
Feb 27 PHP
利用php-cli和任务计划实现订单同步功能的方法
May 03 PHP
PHP实现的分页类定义与用法示例
Jul 05 PHP
php源码的使用方法讲解
Sep 26 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 checkdate、getdate等日期时间函数操作详解
2010/03/11 PHP
PHP自定义函数实现格式化秒的方法
2016/09/14 PHP
CakePHP框架Session设置方法分析
2017/02/23 PHP
javascript 面向对象编程 万物皆对象
2009/09/17 Javascript
jquery 插件开发备注
2010/08/27 Javascript
推荐40个非常优秀的jQuery插件和教程【系列三】
2011/11/09 Javascript
Jquery时间验证和转换工具小例子
2013/07/01 Javascript
做好七件事帮你提升jQuery的性能
2014/02/06 Javascript
jquery实现弹出层遮罩效果的简单实例
2014/03/03 Javascript
详解 javascript中offsetleft属性的用法
2015/11/11 Javascript
Angular+Bootstrap+Spring Boot实现分页功能实例代码
2017/07/21 Javascript
mui开发中获取单选按钮、复选框的值(实例讲解)
2017/07/24 Javascript
js的函数的按值传递参数(实例讲解)
2017/11/16 Javascript
在angular 6中使用 less 的实例代码
2018/05/13 Javascript
webpack 样式加载的实现原理
2018/06/12 Javascript
vue.js 图片上传并预览及图片更换功能的实现代码
2018/08/27 Javascript
Bootstarp在pycharm中的安装及简单的使用方法
2019/04/19 Javascript
微信小程序解析富文本过程详解
2019/07/13 Javascript
JS中比Switch...Case更优雅的多条件判断写法
2019/09/05 Javascript
VUE实现密码验证与提示功能
2019/10/18 Javascript
vue实现输入一位数字转汉字功能
2019/12/13 Javascript
Vue 中如何将函数作为 props 传递给组件的实现代码
2020/05/12 Javascript
使用vue编写h5公众号跳转小程序的实现代码
2020/11/27 Vue.js
Python基于回溯法子集树模板解决0-1背包问题实例
2017/09/02 Python
Python实现控制台中的进度条功能代码
2017/12/22 Python
浅谈Matplotlib简介和pyplot的简单使用——文本标注和箭头
2018/01/09 Python
python中requests和https使用简单示例
2018/01/18 Python
Python SqlAlchemy动态添加数据表字段实例解析
2018/02/07 Python
Python 打印中文字符的三种方法
2018/08/14 Python
实例详解Python模块decimal
2019/06/26 Python
Foot Locker澳洲官网:美国运动服和鞋类零售商
2019/10/11 全球购物
大家检讨书5000字
2014/02/03 职场文书
《我为你骄傲》教学反思
2014/02/20 职场文书
综合实践活动总结
2014/05/05 职场文书
加强机关作风建设心得体会
2014/10/22 职场文书
二年级上册数学教学计划
2015/01/20 职场文书