如何将旧版函数exec_SELECT_mm_query迁移到TYPO3中基于Doctrine的Querybuilder / Connection

时间:2019-04-03 12:37:51

标签: typo3

假设以下代码段:

$res = $GLOBALS['TYPO3_DB']->exec_SELECT_mm_query(
    $foreign . '.*', $local, $mm, $foreign, 'AND ' . $local . '.uid=' . $constraintUid);

while ($r=$GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
...
  • $ foreign / foreign:外部数据库表的名称
  • $ local / local:本地数据库表的名称
  • $ mm / mm:关系数据库表的名称(通常是someorother_mm)
  • $ constraintUid / constraintUid:一些uid

我想使用基于Doctrine的数据库功能将代码迁移到TYPO3 9。


上面的代码被转换为以下SQL语句:

SELECT foreign.* FROM local,mm,foreign 
    WHERE    local.uid=mm.uid_local 
        AND  foreign.uid=mm.uid_foreign 
        AND  local.uid = constraintUid

请参见exec_SELECT_mm_query

参数:

  • 字符串$ select SELECT的字段列表
  • 字符串$ local_table表名,本地表
  • 字符串$ mm_table表名,关系表
  • 字符串$ foreign_table表名,外部表
  • string $ whereClause放置了可选的附加WHERE子句 查询的结尾。 ...
  • ...

2 个答案:

答案 0 :(得分:0)

我是在自我回答,但是如果有人有更好的解决方案,请随时添加答案。


原始查询语句可以使用JOIN转换为语句。这也使它更具可读性,因为WHERE子句由JOIN约束分隔。

所以我们可以使用:

$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
  ->getQueryBuilderForTable($foreign);
// set uid
$constraints[] = $queryBuilder->expr()->eq(
  $local . '.uid', 
  $queryBuilder->createNamedParameter($item, \PDO::PARAM_INT)
);

// optionally add more constraints ...

$rows = $queryBuilder
  ->select($foreign . '.*')
  ->from($foreign)
  ->join(
    $foreign,
    $mm,
    $mm,
    $queryBuilder->expr()->eq(
      $foreign . '.uid', 
      $queryBuilder->quoteIdentifier($mm . '.uid_foreign')
    )
  )
  ->join(
    $mm,
    $local,
    $local,
    $queryBuilder->expr()->eq(
      $local . '.uid', 
      $queryBuilder->quoteIdentifier($mm . '.uid_local')
    )
)
->where(...$constraints)
->execute()
->fetchAll();

foreach ($rows as $row) {

这将转换为以下SQL语句:(我省略了AND deleted=0等,它会自动添加到TYPO3中的约束中。)

SELECT foreign.* FROM foreign
INNER JOIN mm mm
  ON foreign.uid = mm.uid_foreign 
INNER JOIN local local
  ON local.uid = mm.uid_local
WHERE local.uid = constraintUid

出于优化目的,这些字段可能会减少为实际需要的字段。

答案 1 :(得分:0)

我的建议是:

$foreign = 'a';
$mm = 'mm';
$local = 'b';
$item = 1;

/** @var \TYPO3\CMS\Core\Database\Query\QueryBuilder $queryBuilder */
$queryBuilder = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
    \TYPO3\CMS\Core\Database\ConnectionPool::class
)->getQueryBuilderForTable($foreign);
$expr = $queryBuilder->expr();

/** @var \Doctrine\DBAL\Driver\Statement $rows */
$rows = $queryBuilder
    ->select('foreign.*')
    ->from($foreign, 'foreign')
    ->innerJoin('foreign', $mm, 'mm', $expr->eq('foreign.uid', 'mm.uid_foreign'))
    ->innerJoin('mm', $local, 'local', $expr->eq('mm.uid_local', 'local.uid'))
    ->where(
        $expr->eq('local.uid', $queryBuilder->createNamedParameter($item, \PDO::PARAM_INT))
    )
    ->execute();

while (($row = $rows->fetch()) != null) {
}