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 相关文章推荐
IIS6的PHP最佳配置方法
Mar 19 PHP
PHP网站备份程序代码分享
Jun 10 PHP
初学PHP的朋友 经常问的一些问题。不断更新
Aug 11 PHP
PHP遍历数组的几种方法
Mar 22 PHP
php验证手机号码(支持归属地查询及编码为UTF8)
Feb 01 PHP
php读取文件内容的几种方法详解
Jun 26 PHP
PHP SPL使用方法和他的威力
Nov 12 PHP
php判断页面是否是微信打开的示例(微信打开网页)
Apr 25 PHP
php精确的统计在线人数的方法
Oct 21 PHP
Laravel框架实现修改登录和注册接口数据返回格式的方法
Aug 17 PHP
php随机生成验证码,php随机生成数字,php随机生成数字加字母!
Apr 01 PHP
tp5使用layui实现多个图片上传(带附件选择)的方法实例
Nov 17 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实现适用于自定义的验证码类
2016/06/15 PHP
PHP date_default_timezone_set()设置时区操作实例分析
2020/05/16 PHP
jquery js 重置表单 reset()具体实现代码
2013/08/05 Javascript
JS动态添加与删除select中的Option对象(示例代码)
2013/12/20 Javascript
JavaScript实现非常简单实用的下拉菜单效果
2015/08/27 Javascript
js基础知识(公有方法、私有方法、特权方法)
2015/11/06 Javascript
jQuery1.9+中删除了live以后的替代方法
2016/06/17 Javascript
jquery,js简单实现类似Angular.js双向绑定
2017/01/13 Javascript
微信小程序 商城开发(ecshop )简单实例
2017/04/07 Javascript
AngularJS获取json数据的方法详解
2017/05/27 Javascript
Mint UI 基于 Vue.js 移动端组件库
2017/11/07 Javascript
基于bootstrap写的一点localStorage本地储存
2017/11/21 Javascript
JS高阶函数原理与用法实例分析
2019/01/15 Javascript
通过实例学习React中事件节流防抖
2019/06/17 Javascript
Element Steps步骤条的使用方法
2020/07/26 Javascript
如何使用JS console.log()技巧提高工作效率
2020/10/14 Javascript
[00:37]DOTA2上海特级锦标赛 OG战队宣传片
2016/03/03 DOTA
在Python中测试访问同一数据的竞争条件的方法
2015/04/23 Python
Python爬虫_城市公交、地铁站点和线路数据采集实例
2018/01/10 Python
Django框架设置cookies与获取cookies操作详解
2019/05/27 Python
python 定时器每天就执行一次的实现代码
2019/08/14 Python
python/Matplotlib绘制复变函数图像教程
2019/11/21 Python
python3实现弹弹球小游戏
2019/11/25 Python
python编写softmax函数、交叉熵函数实例
2020/06/11 Python
使用Python项目生成所有依赖包的清单方式
2020/07/13 Python
英国在线花园中心:You Garden
2018/06/03 全球购物
机电专业毕业生推荐信
2013/11/10 职场文书
抄作业检讨书
2014/02/17 职场文书
爱国卫生月实施方案
2014/02/21 职场文书
机关单位人员学雷锋心得体会
2014/03/10 职场文书
全国爱眼日活动总结
2015/02/27 职场文书
土建技术员岗位职责
2015/04/11 职场文书
杨善洲观后感
2015/06/04 职场文书
《穷人》教学反思
2016/02/19 职场文书
详解NodeJS模块化
2021/06/15 NodeJs
Nginx静态压缩和代码压缩提高访问速度详解
2022/05/30 Servers