php语言

Yii2如何实现跨mysql数据库关联查询排序

时间:2025-04-30 02:19:05 php语言 我要投稿
  • 相关推荐

Yii2如何实现跨mysql数据库关联查询排序

  导语:Yii2如何实现跨mysql数据库关联查询排序呢?下面是小编给大家提供的代码实现教程,大家可以参考阅读,更多详情请关注应届毕业生考试网。

  背景:在一个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')?>

  //其他列

  <p class="form-group">

  <?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>

  </p>

  <?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');

  }

【Yii2如何实现跨mysql数据库关联查询排序】相关文章:

PHP 中 MySQL 数据库异步查询实现08-22

如何实现yii2 数据库读写分离配置07-01

如何实现归并排序10-04

php如何实现快速排序09-18

php基础之连接mysql数据库和查询数据07-30

关于php操作mysql执行数据库查询08-11

PHP获取MySQL数据库里所有表的实现代码08-27

PHP与MYSql连接与查询06-19

php查询mysql的实例09-09