Подтвердить что ты не робот

LEFT JOIN в ZF2 с использованием TableGateway

У меня есть таблица:

*CREATE TABLE IF NOT EXISTS `blogs_settings` (
  `blog_id` int(11) NOT NULL AUTO_INCREMENT,
  `owner_id` int(11) NOT NULL,
  `title` varchar(255) NOT NULL,
  `meta_description` text NOT NULL,
  `meta_keywords` text NOT NULL,
  `theme` varchar(25) NOT NULL DEFAULT 'default',
  `is_active` tinyint(1) NOT NULL DEFAULT '1',
  `date_created` int(11) NOT NULL,

  PRIMARY KEY (`blog_id`),
  KEY `owner_id` (`owner_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;*

И вторая таблица:

*CREATE TABLE IF NOT EXISTS `users` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  `password` varchar(128) NOT NULL,
  `sex` tinyint(1) NOT NULL,
  `birthday` date NOT NULL,
  `avatar_id` int(11) DEFAULT NULL,
  `user_level` tinyint(1) NOT NULL DEFAULT '1',
  `date_registered` int(11) NOT NULL,
  `is_active` tinyint(1) NOT NULL DEFAULT '0',
  `is_banned` tinyint(1) NOT NULL DEFAULT '0',

  PRIMARY KEY (`user_id`),
  KEY `is_active` (`is_active`),
  KEY `user_level` (`user_level`),
  KEY `is_banned` (`is_banned`),
  KEY `username` (`username`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;*

Как я могу выбрать все поля из таблицы blogs_settings и соединить только поле "имя пользователя" из таблицы пользователей, используя TableGateway в ZF2, на blogs_settings.owner_id = users.user_id. Заранее спасибо. Ваша помощь очень ценится.

EDIT:

namespace Object\Model;

use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Sql\Select;

class BlogsSettingsTable {

protected $tableGateway;
protected $select;

public function __construct(TableGateway $tableGateway) {
    $this->tableGateway = $tableGateway;
    $this->select = new Select();
}

public function getBlogs($field = '', $value = '') {
    $resultSet = $this->tableGateway->select(function(Select $select) {
                $select->join('users', 'blogs_settings.owner_id = users.user_id', array('username'));
            });

    return $resultSet;
}

public function getBlog($blogID) {
    $id = (int) $blogID;

    $rowset = $this->tableGateway->select(array('blog_id' => $id));
    $row = $rowset->current();

    if (!$row) {
        throw new Exception('Could not find row with ID = ' . $id);
    }

    return $row;
}

public function addBlog(BlogsSettings $blog) {
    $data = array(
        'owner_id' => $blog->owner_id,
        'title' => $blog->title,
        'meta_description' => $blog->meta_description,
        'meta_keywords' => $blog->meta_keywords,
        'theme' => $blog->theme,
        'is_active' => $blog->is_active,
        'date_created' => $blog->date_created,
    );

    $this->tableGateway->insert($data);
}

public function deleteBlog($blogID) {
    return $this->tableGateway->delete(array('blog_id' => $blogID));
}

}

При этом он выполняет следующий запрос:

SELECT blogs_settings. *, users. username AS username FROM blogs_settings INNER JOIN users ВКЛ blogs_settings. owner_id= users. user_id

но resultSet не содержит поля имени пользователя из объединенной таблицы пользователей. Однако, когда я запускаю запрос в phpmyadmin, все в порядке, и у меня есть поле "имя пользователя" из объединенной таблицы пользователей. В чем проблема?

РЕДАКТИРОВАТЬ 2 ok, я теперь попробовал следующее:

public function getBlogs() {
    $select = $this->tableGateway->getSql()->select();
    $select->columns(array('blog_id', 'interest_id', 'owner_id', 'title', 'date_created'));
    $select->join('users', 'users.user_id = blogs_settings.owner_id', array('username'), 'left');

    $resultSet = $this->tableGateway->selectWith($select);

    return $resultSet;
}

выполненный запрос:

SELECT `blogs_settings`.`blog_id` AS `blog_id`, `blogs_settings`.`interest_id` AS `interest_id`, `blogs_settings`.`owner_id` AS `owner_id`, `blogs_settings`.`title` AS `title`, `blogs_settings`.`date_created` AS `date_created`, `users`.`username` AS `username` FROM `blogs_settings` LEFT JOIN `users` ON `users`.`user_id` = `blogs_settings`.`owner_id`

Когда я запускаю его в phpmyadmin, он присоединяется к полю username из таблицы users. Когда в zf2 это не так.

Здесь дамп всего объекта:

Zend\Db\ResultSet\ResultSet Object
(
[allowedReturnTypes:protected] => Array
    (
        [0] => arrayobject
        [1] => array
    )

[arrayObjectPrototype:protected] => Object\Model\BlogsSettings Object
    (
        [blog_id] => 
        [interest_id] => 
        [owner_id] => 
        [title] => 
        [meta_description] => 
        [meta_keywords] => 
        [theme] => 
        [is_active] => 
        [date_created] => 
    )

[returnType:protected] => arrayobject
[buffer:protected] => 
[count:protected] => 1
[dataSource:protected] => Zend\Db\Adapter\Driver\Pdo\Result Object
    (
        [statementMode:protected] => forward
        [resource:protected] => PDOStatement Object
            (
                [queryString] => SELECT `blogs_settings`.`blog_id` AS `blog_id`, `blogs_settings`.`interest_id` AS `interest_id`, `blogs_settings`.`owner_id` AS `owner_id`, `blogs_settings`.`title` AS `title`, `blogs_settings`.`date_created` AS `date_created`, `users`.`username` AS `username` FROM `blogs_settings` LEFT JOIN `users` ON `users`.`user_id` = `blogs_settings`.`owner_id`
            )

        [options:protected] => 
        [currentComplete:protected] => 
        [currentData:protected] => 
        [position:protected] => -1
        [generatedValue:protected] => 0
        [rowCount:protected] => 1
    )

[fieldCount:protected] => 6
[position:protected] => 
)

Вверх... любые идеи?

4b9b3361

Ответ 1

Добавление в @samsonasik ответа и решение проблем в его комментариях. Вы не сможете получить объединенные значения из того, что возвращается из этого утверждения. Этот оператор возвращает объект модели, у которого не будет объединенных строк. Вам нужно будет выполнить его как SQL на уровне, который подготовит его как необработанный SQL и вернет вам каждую результирующую строку как массив, а не объект:

$sqlSelect = $this->tableGateway->getSql()->select();
$sqlSelect->columns(array('column_name_yourtable'));
$sqlSelect->join('othertable', 'othertable.id = yourtable.id', array('column_name_othertable'), 'left');

$statement = $this->tableGateway->getSql()->prepareStatementForSqlObject($sqlSelect);
$resultSet = $statement->execute();
return $resultSet;

//then in your controller or view:

foreach($resultSet as $row){
    print_r($row['column_name_yourtable']);
    print_r($row['column_name_othertable']);
}

Ответ 2

если вы используете TableGateway, вы можете выбрать join, подобный этому

$sqlSelect = $this->tableGateway->getSql()->select();
$sqlSelect->columns(array('column_name'));
$sqlSelect->join('othertable', 'othertable.id = yourtable.id', array(), 'left');

$resultSet = $this->tableGateway->selectWith($sqlSelect);
return $resultSet;

Ответ 3

Вы должны указать поле имени пользователя в модели BlogsSetting, которая используется как модель из BlogsSettingTable (The TableGateway)

class BlogsSetting {
    public $blog_id;
    public $interest_id;
    public $owner_id;
    public $title;
    public $meta_description;
    public $meta_keywords;
    public $theme;
    public $is_active;
    public $date_created;
    public $username;

    public function exchangeArray($data)
    {
        // Create exchangeArray
    }
}

Надеюсь, что это поможет

Ответ 4

Это точная потребность как для Присоединиться, так и Где с помощью tableGateway.

public function getEmployeefunctionDetails($empFunctionId) {
    $empFunctionId = ( int ) $empFunctionId;
    //echo '<pre>'; print_r($this->tableGateway->getTable()); exit;
    $where = new Where();
    $where->equalTo('FUNCTION_ID', $empFunctionId);

    $sqlSelect = $this->tableGateway->getSql()->select()->where($where);    

    $sqlSelect->columns(array('FUNCTION_ID'));
    $sqlSelect->join('DEPARTMENTS', 'DEPARTMENTS.DEPARTMENT_ID = EMPLOYEE_FUNCTIONS.DEPARTMENT_ID', array('DEPARTMENT_ID','DEPARTMENT_NAME'), 'inner');
    $sqlSelect->join('ROLES', 'ROLES.ROLE_ID = EMPLOYEE_FUNCTIONS.ROLE_ID', array('ROLE_ID','ROLE_NAME'), 'inner');

    //echo $sqlSelect->getSqlString(); exit;
    $resultSet = $this->tableGateway->selectWith($sqlSelect);

    if (! $resultSet) {
        throw new \Exception ( "Could not find row $empFunctionId" );
    }
    return $resultSet->toArray();
}

Ответ 5

В вашем классе, унаследованном от AbstractTableGateway, вы можете использовать Select with Closure следующим образом:

use Zend\Db\Sql\Select;
...
public function getAllBlockSettings()
{
    $resultSet = $this->select(function(Select $select) {
        $select->join('users', 'blogs_settings.owner_id = users.user_id', array('username'));
    });

    return $resultSet;
}

Ответ 6

Попробуйте:

namespace Object\Model;

use Zend\Db\TableGateway\AbstractTableGateway;
use Zend\Db\Sql\Select;

class BlogsSettingsTbl extends AbstractTableGateway {
    public function __construct($adapter) {
        $this->table = 'blogs_settings';
        $this->adapter = $adapter;
        $this->initialize();
    }

    public function fetchAll() {
        $where = array(); // If have any criteria
        $result = $this->select(function (Select $select) use ($where) {
                    $select->join('users', 'blogs_settings.owner_id = users.user_id', array('username'));
                    //echo $select->getSqlString(); // see the sql query
                });
        return $result;
    }
}

Добавить в 'getServiceConfig()' в Module.php:

'Object\Model\BlogsSettingsTbl' => function($sm) {
    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
    $table = new BlogsSettingsTbl($dbAdapter); // <-- also add this to 'USE' at top
    return $table;
},

Ответ 7

поскольку OP не принял никакого ответа, я попытаюсь дать решение. Я сталкиваюсь с тем же решением, что и состояния OP, и единственный способ его исправить - это добавить эту строку в класс модели (в данном случае это может быть "Blogsetttings.php" ).

$this->username= (!empty($data['username'])) ? $data['username'] : null;

вы должны добавить выше строку к методу exchangeArray(). Надеюсь, что это поможет.