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 相关文章推荐
PHP输出控制功能在简繁体转换中的应用
Oct 09 PHP
搜索引擎技术核心揭密
Oct 09 PHP
五款PHP代码重构工具推荐
Oct 14 PHP
thinkphp模板赋值与替换实例简述
Nov 24 PHP
PHP+Mysql+jQuery文件下载次数统计实例讲解
Oct 10 PHP
yii实现使用CUploadedFile上传文件的方法
Dec 28 PHP
php上传图片获取路径及给表单字段赋值的方法
Jan 23 PHP
java微信开发之上传下载多媒体文件
Jun 24 PHP
PHP查看SSL证书信息的方法
Sep 22 PHP
Yii2实现log输出到file及database的方法
Nov 12 PHP
php 中的信号处理操作实例详解
Mar 04 PHP
Yii使用EasyWechat实现小程序获取用户的openID的方法
Apr 29 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
PHP4实际应用经验篇(9)
2006/10/09 PHP
PHP图片上传类带图片显示
2006/11/25 PHP
fetchAll()与mysql_fetch_array()的区别详解
2013/06/05 PHP
PHP编程风格规范分享
2014/01/15 PHP
YII使用url组件美化管理的方法
2015/12/28 PHP
PHP处理数组和XML之间的互相转换
2016/06/02 PHP
php实现的后台表格分页功能示例
2017/10/23 PHP
在TP5数据库中四个字段实现无限分类的示例
2019/10/18 PHP
用函数式编程技术编写优美的 JavaScript
2006/11/25 Javascript
Javascript String.replace的妙用
2009/09/08 Javascript
from表单多个按钮提交用onclick跳转不同action
2014/04/24 Javascript
JS处理一些简单计算题
2018/02/24 Javascript
jQuery简单判断值是否存在于数组中的方法示例
2018/04/17 jQuery
详解Vue+axios+Node+express实现文件上传(用户头像上传)
2018/08/10 Javascript
2019 年编写现代 JavaScript 代码的5个小技巧(小结)
2019/01/15 Javascript
详解vue2.6插槽更新v-slot用法总结
2019/03/09 Javascript
解决vue项目运行npm run serve报错的问题
2020/10/26 Javascript
[01:04:05]VG vs Newbee 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
python如何派生内置不可变类型并修改实例化行为
2018/03/21 Python
matlab中实现矩阵删除一行或一列的方法
2018/04/04 Python
python字符串与url编码的转换实例
2018/05/10 Python
修改Pandas的行或列的名字(重命名)
2019/12/18 Python
css3+jq创作含苞待放的荷花
2014/02/20 HTML / CSS
几个解决兼容IE6\7\8不支持html5标签的几个方法
2013/01/07 HTML / CSS
AmazeUI 列表的实现示例
2020/08/17 HTML / CSS
STAUD官方网站:洛杉矶独有的闲适风格
2019/04/11 全球购物
Lacoste(法国鳄鱼)加拿大官网:以标志性的POLO衫而闻名
2019/05/15 全球购物
意大利在线药房:Farmacia Loreto Gallo
2019/08/09 全球购物
丝芙兰意大利官方网站:Sephora.it
2019/12/13 全球购物
英国门销售网站:Green Tree Doors
2020/01/07 全球购物
教师演讲稿范文
2014/01/08 职场文书
2015感人爱情寄语
2015/02/26 职场文书
2016年寒假生活小结
2015/10/10 职场文书
新店开业策划方案怎么书写?
2019/07/05 职场文书
小学生优秀作文范文(六篇)
2019/07/10 职场文书
Python内置数据类型中的集合详解
2022/03/18 Python