如何使用doctrine/symfony4从数据库中获取(加入)两条记录

hid*_*dar 11 php mysql symfony doctrine-orm symfony4

我正在学习Symfony和Doctrine,并创建了一个简单的网站,但我坚持这一步.

我有两张桌子:userslanguages

用户包含:id,username ...
语言包含:user_id,language ...

这是两个图像在此输入图像描述

在此输入图像描述

现在我想通过语言来获取,如:获取用户谁讲都english french其结果将返回用户ID 2

在普通的PHP中,我可以使用PDO进行内部联接,但我试图遵循教义语法,这不会返回正确的结果

public function getMatchingLanguages ($a, $b) {
  return $this->createQueryBuilder('u')
    ->andWhere('u.language = :val1 AND u.language = :val2')
    ->setParameter('val1', $a)
    ->setParameter('val2', $b)
    ->getQuery()
    ->execute();
}
Run Code Online (Sandbox Code Playgroud)

我在我的控制器中调用此方法,并且查询非常基本,因为我找不到文档如何按照我的示例进行连接

Igo*_*lev 6

在您的用户模型中添加下一个代码:

/**
 * @ORM\OneToMany(targetEntity="Language", mappedBy="user", fetch="EXTRA_LAZY")
 */
public $languages;
Run Code Online (Sandbox Code Playgroud)

在语言模型中添加下一个代码:

/**
 * @ORM\ManyToOne(targetEntity="User", inversedBy="languages")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 * })
 */
public $user;
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以在用户和语言之间定义简单的一对多关系,但这不足以让您的用户支持这两种语言.您需要进行2个用户表和语言表的连接.这就是它的样子(如果你使用控制器):

  $user = $this->get('doctrine')
        ->getEntityManager()
        ->createQueryBuilder()
        ->select('u')
        ->from(User::class, 'u')
        ->join('u.languages', 'l_eng', 'WITH', 'l_eng.language = :engCode')
        ->join('u.languages', 'l_fr', 'WITH', 'l_fr.language = :frCode')
        ->setParameters([
            'engCode' => 'english',
            'frCode' => 'french'
        ])
        ->getQuery()->execute();
Run Code Online (Sandbox Code Playgroud)

或者,如果您使用UserRepository类(最优选):

public function findAllByLangs()
{
    return $this->createQueryBuilder('u')
        ->join('u.languages', 'l_eng', 'WITH', 'l_eng.lang = :engCode')
        ->join('u.languages', 'l_fr', 'WITH', 'l_fr.lang = :frCode')
        ->setParameters([
            'engCode' => 'english',
            'frCode' => 'french'
        ])
        ->getQuery()->execute();
}
Run Code Online (Sandbox Code Playgroud)

因此,主要的窍门是加入语言表的英语条件来过滤用户,支持英语再次但是法国人在参加语言表"ON"部分过滤谁支持法语的用户,以及.


han*_*gla 2

通过分析您的数据库表,我假设您的实体是这样的

// 用户.php

class User implements UserInterface
{
    /**
     * @ORM\Column(type="guid")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="UUID")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $username;
}
Run Code Online (Sandbox Code Playgroud)

// 语言.php

class Language
{

    /**
     * @ORM\Column(type="guid")
     */
    private $userId;

    /**
     * @ORM\Column(type="string", length=30)
     */
    private $language;
}
Run Code Online (Sandbox Code Playgroud)

如果您有相同的设置(如上面的实体),那么您可以在 UserRepository.php 中编写这样的查询

public function getUsersForMatchingLanguages ($langOne, $langTwo) {
    return $this->createQueryBuilder('user')
        ->select('user.id, user.username, language.language')
        ->innerJoin(Language::class, 'language', 'WITH', 'language.user_id = user.id')
        ->where('language.language = :langOne AND language.language = :langTwo')
        ->setParameter('langOne ', $langOne )
        ->setParameter('langTwo', $langTwo)
        ->getQuery()
        ->getResult();
}
Run Code Online (Sandbox Code Playgroud)

这将返回结果数组。

  • 通常,您不必“认为”答案是正确的。你应该很清楚了。也许通过在发布之前进行测试。你的加入完全混乱了。即使你解决了这个问题,IN 子句的使用也表明你不理解原来的问题。 (2认同)