2013-02-11 2 views
17

У меня есть таблица: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)); 
} 

}

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

ЗЕЬЕСТ blogs_settings *, users. username AS username ОТ blogs_settings INNER JOIN users ON blogs_settings. owner_id = users. user_id

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

EDIT 2 нормально, теперь я попробовал следующее:

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, он присоединяется поле имя пользователя из таблица пользователей. Когда в 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] => 
) 

Up ... любые идеи?

+0

Duplicate? -> http://stackoverflow.com/questions/14354802/tablegateway-with-multiple-from-tables/14371056#14371056 – Crisp

+0

Это не объяснено, и я не уверен, как написать свой запрос. Можете ли вы мне помочь с конкретным объяснением того, как присоединиться к таблице mysql? –

+0

вид блокировки и выборки только столбцов, которые определены в вашем классе «BlogSettings» (см. '__construct (TableGateway $ tableGateway)') – webcoder

ответ

12

Добавление к ответу @ 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']); 
} 
+1

Решил это для меня! Спасибо тонну, я не могу поверить, насколько сложно это просто для простого соединения ... –

+0

Без проблем @MichaelLumbroso :) – Pakage

+0

Ты мужчина, спасибо большое! Я потратил последние 3 часа, пытаясь понять это. Если бы я мог бы дать вам +10 :) –

1

В классе унаследовал от AbstractTableGateway и можно использовать Select с закрытия так:

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; 
} 
+0

И как именно выглядит экземпляр TableGateway, который вы вставляете в конструктор? – TobiasDeVil

+0

Вся модель находится в моем первом посте. –

+0

Есть ли способ запустить сырой sql-запрос в базе данных с помощью TableGateway? –

12

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

$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; 
+2

Кажется, что проблема связана не с запросом, а с самим результатом. Когда я запускаю свой запрос в phpmyadmin, он работает, когда я хочу отображать результаты в представлении zf2, он, похоже, не работает. –

+0

Да @ ГеоргиБанков прав. Если это var_dump в представлении, вы можете увидеть запрос, и этот запрос будет идеальным. Но это значения равны нулю и не могут быть доступны из представления. Может кто-нибудь, пожалуйста, дайте решение для этого – Ruwantha

+0

@samsonasik, как неудобно для этого работать? Я всегда получаю 'Метод' Double \ TableGatewayInterface \ P7 :: getSql() 'не найден .' – rogaa

1

Дайте ему попробовать :

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()' в модуле.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; 
}, 
2

Вы должны включить имя пользователя в поле Модели 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 
    } 
} 

Надеется, что это помогает

0

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

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

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

2

Это точная потребность как Регистрация и Где положения с 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(); 
} 
+0

использовать Zend \ Db \ TableGateway \ TableGateway; // используем Zend \ Db \ Sql \ Sql; использование Zend \ Db \ Sql \ Select; использование Zend \ Db \ Sql \ Where; – Dhiraj

 Смежные вопросы

  • Нет связанных вопросов^_^