承接 yii2tech/ar-eagerjoin 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

yii2tech/ar-eagerjoin

最新稳定版本:1.0.2

Composer 安装命令:

composer require yii2tech/ar-eagerjoin

包简介

Provides support for ActiveRecord relation eager loading via join without extra query in Yii2

README 文档

README

12951949

ActiveRecord Eager Join Extension for Yii 2


This extension provides support for ActiveRecord relation eager loading via 'join' without extra query.

For license information check the LICENSE-file.

Latest Stable Version Total Downloads Build Status

Installation

The preferred way to install this extension is through composer.

Either run

php composer.phar require --prefer-dist yii2tech/ar-eagerjoin

or add

"yii2tech/ar-eagerjoin": "*"

to the require section of your composer.json.

Usage

This extension provides support for ActiveRecord relation eager loading via 'join' without extra query. Imagine we have the following database structure:

CREATE TABLE `Group`
(
   `id` integer NOT NULL AUTO_INCREMENT,
   `name` varchar(64) NOT NULL,
   `code` varchar(10) NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE InnoDB;

CREATE TABLE `Item`
(
   `id` integer NOT NULL AUTO_INCREMENT,
   `groupId` integer NOT NULL,
   `name` varchar(64) NOT NULL,
   `price` float,
    PRIMARY KEY (`id`)
    FOREIGN KEY (`groupId`) REFERENCES `Group` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
) ENGINE InnoDB;

If you need to display listing of items, with the groups they belong to, ordered by group name or code, you'll have to use JOIN SQL statement and thus - \yii\db\ActiveQuery::joinWith() method:

$items = Item::find()
    ->joinWith('group')
    ->orderBy(['{{group}}.[[name]]' => SORT_ASC])
    ->all();

However, the code above will perform 2 SQL queries: one - for the item fetching (including JOIN and ORDER BY statements) and second - for the group fetching. While second query will be very simple and fast, it is still redundant and unefficient, since all group columns may be selected along with the item ones.

This extension provides [[yii2tech\ar\eagerjoin\EagerJoinTrait]] trait, which, once used in the ActiveRecord class, allows selecting related records without extra SQL query.

Setup example:

use yii\db\ActiveRecord;
use yii2tech\ar\eagerjoin\EagerJoinTrait;

class Item extends ActiveRecord
{
    use EagerJoinTrait;

    public function getGroup()
    {
        return $this->hasOne(Group::className(), ['id' => 'groupId']);
    }
}

In order to populate related record though 'join' query, you'll need to manually append its columns into the SELECT query section and alias them by names in following format:

{relationName}{boundary}{columnName}

where:

  • 'relationName' - name of the relation to be populated
  • 'columnName' - name of the column(attribute) of the related record to be filled
  • 'boundary' - separator configured by [[yii2tech\ar\eagerjoin\EagerJoinTrait::eagerJoinBoundary()]]

For example:

$items = Item::find()
    ->select(['Item.*', 'group__name' => 'Group.name', 'group__code' => 'Group.code'])
    ->joinWith('group', false) // disable regular eager loading!!!
    ->all();

foreach ($items as $item) {
    var_dump($item->isRelationPopulated('group')); // outputs `true`!!!
    echo $item->group->name; // no extra query performed!
    echo $item->group->code; // no extra query performed!
    echo get_class($item->group); // outputs 'Group'!
}

Here 'group__name' column of the query result set is passed to $item->group->name, 'group__code' - to $item->group->code and so on.

Heads up! Do not forget to disable eager loading, passing false as second argument of joinWith() method, otherwise you'll gain no benefit.

Note: choose boundary carefully: it should not be present as a part of the columns (or aliases), which are not meant to be passed to the related records. Thus double underscore ('__') is used as default.

Tip: if you use 'camelCase' notation for your table columns, you may use single underscore ('_') as a boundary in order to make select statements more clear.

You may speed up composition of the query for the eager join using [[\yii2tech\ar\eagerjoin\EagerJoinQueryTrait]] trait. This trait should be used in the [[\yii\db\ActiveQuery]] instance:

use yii\db\ActiveQuery;
use yii2tech\ar\eagerjoin\EagerJoinQueryTrait;
use yii\db\ActiveRecord;
use yii2tech\ar\eagerjoin\EagerJoinTrait;

class ItemQuery extends ActiveQuery
{
    use EagerJoinQueryTrait;

    // ...
}

class Item extends ActiveRecord
{
    use EagerJoinTrait;

    /**
     * @inheritdoc
     * @return ItemQuery the active query used by this AR class.
     */
    public static function find()
    {
        return new ItemQuery(get_called_class());
    }

    // ...
}

Then you'll be able to use eagerJoinWith() method while building a query:

$items = Item::find()->eagerJoinWith('group')->all();

Composition of the proper 'select' and 'join' statements will be performed automatically.

Restrictions and drawbacks

While reducing the number of executed queries, this extension has several restrictions and drawbacks.

  1. Only 'has-one' relations are supported. Extension is unable to handle 'has-many' relations. You should use regular joinWith() and eager loading for 'has-many' relations.

  2. If all selected related model fields will be null, the whole related record will be set to null. You should always select at least one 'not null' column to avoid inappropriate results.

  3. Despite extra query removal, this extension may not actually increase overall performance. Regular Yii eager join query is very simple and fast, while this extension consumes extra memory and performs extra calculations. Thus in result performance remain almost the same. In most cases usage of this extension is a tradeoff: it reduces load on Database side, while increases it on PHP side.

yii2tech/ar-eagerjoin 适用场景与选型建议

yii2tech/ar-eagerjoin 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 18.89k 次下载、GitHub Stars 达 22, 最近一次更新时间为 2016 年 02 月 04 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「relation」 「join」 「active」 「record」 「yii2」 「eager」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 yii2tech/ar-eagerjoin 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 yii2tech/ar-eagerjoin 我们能提供哪些服务?
定制开发 / 二次开发

基于 yii2tech/ar-eagerjoin 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 18.89k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 24
  • 点击次数: 18
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 22
  • Watchers: 4
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: BSD-3-Clause
  • 更新时间: 2016-02-04