2013-02-11 19 views
17

Ho una tabella:LEFT JOIN in ZF2 utilizzando 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 ;* 

E la seconda tabella:

*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 ;* 

Come posso selezionare tutti i campi dalla tabella blogs_settings e unisciti solo il 'nome utente' campo dalla tabella utenti utilizzando TableGateway in ZF2, su blogs_settings.owner_id = users.user_id. Grazie in anticipo. Il tuo aiuto è molto apprezzato.

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)); 
} 

}

Con questo, esegue la seguente query:.

SELEZIONARE blogs_settings *, users. username AS username DA blogs_settings INNER JOIN users ON blogs_settings. owner_id = users. user_id

ma resultSet non contiene il campo nome utente dalla tabella 'utenti' unita. Tuttavia, quando eseguo la query in phpmyadmin, tutto è ok e ho il campo 'username' dalla tabella 'users' unita. Qual è il problema?

EDIT 2 ok, ora provato la seguente:

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

la query eseguita è:

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` 

Quando eseguo in phpMyAdmin, si unisce il campo nome utente dal tabella degli utenti. Quando in zf2, non è così.

Ecco il dump del tutto l'oggetto:

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 ... tutte le idee?

+0

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

+0

Non è spiegato e io non sono sicuro di come scrivere la mia domanda. Mi aiuti con una spiegazione concreta su come partecipare a un tavolo MySQL? –

+0

tipo di blocco e andare a prendere solo le colonne che sono definite nella classe 'BlogSettings' (vedere '__construct (TableGateway $ tableGateway)') – webcoder

risposta

12

Aggiunta alla risposta di @ samsonasik e risoluzione dei problemi nei commenti. Non sarà possibile ottenere i valori uniti da ciò che viene restituito da tale istruzione. Tale istruzione restituisce l'oggetto modello che non avrà le righe unite. Avrete bisogno di eseguirlo come SQL ad un livello che preparerà come SQL prime e si torna ogni riga risultante come una matrice piuttosto che un oggetto:

$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

Risolto per me! Grazie una tonnellata, non riesco a credere quanto sia complicato questo è solo per un semplice join ... –

+0

Nessun problema @MichaelLumbroso :) – Pakage

+0

Sei l'uomo, grazie mille! Ho passato le ultime 3 ore a cercare di capirlo. Se potessi, ti darei +10 :) –

1

Nella tua classe ereditata da AbstractTableGateway u possibile utilizzare Select con chiusura in questo modo:

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

Ed esattamente come appare esempio TableGateway che si mette al costruttore? – TobiasDeVil

+0

L'intero modello è nel mio primo post. –

+0

Esiste un modo per eseguire una query sql raw nel database utilizzando TableGateway? –

12

se si sta utilizzando TableGateway, è possibile selezionare partecipare come questo

$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

Sembra che il problema non sia con la query, ma con il risultato recuperato stesso. Quando eseguo la mia query nel phpmyadmin funziona, quando voglio visualizzare i risultati nella vista zf2, non sembra funzionare. –

+0

Sì @ ГеоргиБанков ha ragione. Se var_dump nella vista è possibile visualizzare la query e quella query è perfetta. Ma i valori sono nulli e non è possibile accedervi dalla vista. qualcuno può per favore dare una soluzione a questo – Ruwantha

+0

@samsonasik come è l'unittest per questo lavoro? Ho sempre trovato metodo 'Doppia \ TableGatewayInterface \ P7 :: getSql()' non found.' – rogaa

1

Fate una prova :

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

Aggiungi a 'getServiceConfig()' nel Modulo.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

Bisogna includere campo nome utente nel modello BlogsSetting che viene utilizzato come modello da BlogsSettingTable (Il 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 
    } 
} 

Spero che questo aiuti

0

poiché l'OP non ha accettato qualsiasi risposta, cercherò di dare la soluzione. io faccia la stessa soluzione stati OP e l'unico modo per risolvere il problema è aggiungendo questa riga alla classe del modello (in questo caso potrebbe essere 'Blogsetttings.php').

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

si dovrebbe aggiungere riga sopra al metodo exchangeArray(). Speranza che aiuta

2

Questa è la necessità esatta per entrambi Join e Dove clausole con 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

uso Zend \ Db \ TableGateway \ TableGateway; // usa Zend \ Db \ Sql \ Sql; usa Zend \ Db \ Sql \ Select; usa Zend \ Db \ Sql \ Dove; – Dhiraj