Mysql 使用TableGateway在ZF2中左连接

Mysql 使用TableGateway在ZF2中左连接,mysql,frameworks,zend-framework2,tablegateway,Mysql,Frameworks,Zend Framework2,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

我有一张桌子:

*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 ;*
如何在ZF2中的
blogs\u settings.owner\u id=users.user\u id
上选择blogs\u settings表中的所有字段,并使用TableGateway仅加入users表中的“username”字段。提前谢谢。非常感谢你的帮助

编辑: }

这样,它将执行以下查询:

blogs\u settings
internal JOIN
users

但是resultSet不包含加入的“users”表中的username字段。但是,当我在phpmyadmin中运行查询时,一切都正常,并且我已经加入了“users”表中的“username”字段。有什么问题吗

编辑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中时,它将从users表中加入username字段。在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] => 
)

向上。。。有什么想法吗?

在继承自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;
}

如果您使用的是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;
试一试:

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;
    }
}
添加到Module.php中的“getServiceConfig()”:

'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;
},
'Object\Model\blogsettingstbl'=>函数($sm){
$dbAdapter=$sm->get('Zend\Db\Adapter\Adapter');

$table=new BlogsSettingsTbl($dbAdapter);//您必须在BlogsSetting模型中包含用户名字段,该模型用作BlogsSettingTable(TableGateway)中的模型


希望这有帮助

既然OP还没有接受任何答案,我将尝试给出解决方案。 我面临与OP状态相同的解决方案,唯一的修复方法是将这一行添加到模型类中(在本例中,这可能是'blogsettings.php')

您应该将上面的行添加到exchangeArray()方法中。
希望对您有所帮助

这正是使用tableGatewayJoinWhere子句的需要

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();
}
公共函数getEmployeefunctionDetails($empFunctionId){
$empFunctionId=(int)$empFunctionId;
//回显“”;打印($this->tableGateway->getTable());退出;
$where=新where();
$where->equalTo('FUNCTION_ID',$empFunctionId);
$sqlSelect=$this->tableGateway->getSql()->select()->where($where);
$sqlSelect->columns(数组('FUNCTION_ID'));
$sqlSelect->join('DEPARTMENTS'、'DEPARTMENTS.DEPARTMENT\u ID=EMPLOYEE\u FUNCTIONS.DEPARTMENT\u ID',数组('DEPARTMENT\u ID'、'DEPARTMENT\u NAME')、'inner');
$sqlSelect->join('ROLES','ROLES.ROLE\u ID=EMPLOYEE\u FUNCTIONS.ROLE\u ID',数组('ROLE\u ID','ROLE\u NAME'),'internal');
//echo$sqlSelect->getSqlString();退出;
$resultSet=$this->tableGateway->selectWith($sqlSelect);
如果(!$resultSet){
抛出new\Exception(“找不到行$empFunctionId”);
}
返回$resultSet->toArray();
}

添加到@samsonasik的答案并解决其注释中的问题。您将无法从该语句返回的内容中获取连接值。该语句返回的模型对象将不包含连接行。您需要在将其作为原始SQL准备并返回每个结果的级别上以SQL形式执行它将行设置为数组而不是对象:


重复?->没有解释,我也不知道如何编写我的查询。你能帮我具体解释一下如何加入mysql表吗?这是一种只锁定和获取“BlogSettings”类中定义的列(请参见
\u构造(TableGateway$TableGateway)
)您放入构造函数的TableGateway实例的外观如何?整个模型都在我的第一篇文章中。有没有办法使用TableGateway对数据库运行原始sql查询?问题似乎不在于查询,而在于获取的结果本身。当我在phpmyadmin中运行查询时,当我想显示e结果在zf2视图中,它似乎不起作用。是的@ГБББББаааааöf是正确的。如果它在视图中转储,您可以看到查询,并且该查询是完美的。但是如果它的值为空,并且无法从视图中访问。有人能为它提供解决方案吗this@samsonasikunittest如何工作?我总是得到
Method
Double\TableGatewayInterface\P7::getSql()`找不到。`use Zend\Db\TableGateway\TableGateway;//use Zend\Db\Sql\Sql;use Zend\Db\Sql\Select;use Zend\Db\Sql\Where;帮我解决了它!非常感谢,我不敢相信仅仅是一个简单的连接就有多复杂……没问题@MichaelLumbroso:)你就是那个人,非常感谢!我已经花了3个小时试图解决这个问题。如果可以,我会ld给你+10:)它不能从联接表中获取列。只能获取第一个表的列
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
    }
}
$this->username= (!empty($data['username'])) ? $data['username'] : null;
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();
}
$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']);
}