1

如何使用 TableGateway 在模型表中进行 JOIN?

我的模型/NoticiasTable.php 中有这个:

  protected $tableGateway;

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

  public function fetchAll() {
    $where = new Where();
    $where->isNull('deleted_at');

    $resultSet = $this->tableGateway->select(function (Select $select) use ($where) {
      $select->join('news_photos', 'news_photos.news_id = news.id');
      $select->where($where);
      $select->order('date DESC');
    });
    return $resultSet;
  }

它没有显示任何错误,但结果是空的......如果我删除“加入”它就可以工作。那么,如何在模型表中使用 JOIN 呢?

4

1 回答 1

0

这就是我连接表的方式。

use Zend\Paginator\Adapter\DbSelect;
use Zend\Paginator\Paginator;
use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Sql\Predicate\Expression;


/**
 * Preducate contstants.
 */
const PRE_AND = "AND";
const PRE_OR = "OR";
const PRE_NULL = null;

/**
 * @param bool $pagination
 * @param string $join
 * @param array $tbl1OneCols - content table
 * @param array $tbl2OneCols - the joined table
 * @param string $on
 * @param string $joinType
 * @param null|array|string $where
 * @param null $group
 * @param null $order
 * @param int $limit
 * @param int $offset
 *
 * @return ResultSet|Paginator|null
 */
public function fetchJoin($pagination = false, $join = '', array $tbl1OneCols = [], array $tbl2OneCols = [], $on = '', $joinType = self::JOIN_INNER, $where = null, $group = null, $order = null, $limit = 0, $offset = 0)
{
    $select = $this->tableGateway->getSql()->select();
    $select->join($join, $on, $tbl2OneCols, $joinType);
    $result = $this->prepareQuery($select, $tbl1OneCols, $where, self::PRE_NULL, $group, $order, (int) $limit, (int) $offset);
    if ((bool) $pagination === true) {
        return new Paginator(new DbSelect($result, $this->tableGateway->getAdapter(), $this->tableGateway->getResultSetPrototype()));
    } else {
        $resultSet = $this->tableGateway->selectWith($result);
        $resultSet->buffer();
        if ($resultSet->isBuffered() && $resultSet->valid() && $resultSet->count() > 0) {
            return $resultSet;
        }
        return null;
    }
}

/**
 * Prepare all statements before querying the database.
 *
 * @param Zend\Db\Sql\Select $select
 * @param array $columns
 * @param null|array|string $where
 * @param null $group
 * @param null $predicate
 * @param null $order
 * @param null $limit
 * @param null $offset
 *
 * @return Zend\Db\Sql\Select
 */
private function prepareQuery(\Zend\Db\Sql\Select $select, array $columns = [], $where = null, $predicate = self::PRE_NULL, $group = null, $order = null, $limit = null, $offset = null)
{
    if (!empty($columns)) {
        $select->columns($columns);
    }
    if (is_array($where) && !empty($where)) {
        if (!in_array($predicate, [self::PRE_AND, self::PRE_OR, self::PRE_NULL])) {
            $predicate = self::PRE_NULL;
        }
        $select->where($where, $predicate);
    } elseif (!empty($where) && is_string($where)) {
        $select->where(new Expression($where));
    }
    if (!empty($group)) {
        $select->group($group);
    }
    if (!empty($order)) {
        $select->order($order);
    }
    if (!empty($limit) && $limit > 0) {
        $select->limit($limit);
    }
    if (!empty($offset) && $offset > 0) {
        $select->offset($offset);
    }
    return $select;
}

因为$this->tableGateway我有一个单独的班级。

namespace Admin\Factory\Model;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Admin\Model\Menu;
use Admin\Model\MenuTable;

class MenuTableFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $sm = null)
    {
        $resultSetPrototype = new ResultSet();
        $resultSetPrototype->setArrayObjectPrototype(new Menu());
        $db = $sm->get('Zend\Db\Adapter\Adapter');

        $tableGateway = new TableGateway('menu', $db, null, $resultSetPrototype);
        $table = new MenuTable($tableGateway);

        return $table;
    }
}

现在在控制器内部,假设您要显示所有 X 记录indexAction()

带分页。$this->getView()只是返回 ViewModel。如果您不想分页,只需将第一个参数设置为 false。

/**
 * This action shows the list of all Administrators
 */
public function indexAction()
{
    $this->getView()->setTemplate("admin/administrator/index");
    $paginator = $this->getTable("administrator")->fetchJoin(true, "user", ["user"], ["name"], "administrator.user=user.id", "left");
    $paginator->setCurrentPageNumber((int)$this->getParam("page", 1));
    $paginator->setItemCountPerPage(20);
    $this->getView()->paginator = $paginator;
    return $this->getView();
}

$this->getTable()是一个带有工厂的控制器插件,它ServiceManager在控制器外部调用以保持一切简单。

于 2015-09-25T16:40:49.063 回答