如果我们想通过匹配email或者username字段来找到一个用户。我们会在UserRepository里增加一个findOneByUsernameOrEmail方法:
1 2 3 4 5 6 7 8 9 10 |
// src/Yoda/UserBundle/Entity/UserRepository.php // ... class UserRepository extends EntityRepository { public function findOneByUsernameOrEmail() { // ... todo - get your query on } } |
你可以使用Doctrine查询语言DQL来查询数据,他类似与sql语法。如果你做的事情非常的复杂,你甚至可以使用原生的sql查询。
但大多数的时候,我建议使用这个查询生成器对象。createQueryBuilder并传入一个“别名”。现在添加一个where子句来输入我们的OR逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// src/Yoda/UserBundle/Entity/UserRepository.php // ... public function findOneByUsernameOrEmail($username) { return $this->createQueryBuilder('u') ->andWhere('u.username = :username OR u.email = :email') ->setParameter('username', $username) ->setParameter('email', $username) ->getQuery() ->getOneOrNullResult() ; } |
查询生成器有你期望的每一个方法,例如leftJoin,orderBy和groupBy。他们用起来都很得心应手。
andWhere里面的语句类似于sql,只是我们使用了两个变量作为“占位符”。通过调用setParamete来给变量赋值。之所以分为两个部分,主要是防止sql注入攻击。
要完成查询,还需要调用getQuery,然后调用getOneOrNullResult。getOneOrNullResult顾名思义,就是如果没有找到就返回空,如果找到就返回用户对象。
注意:想要了解更多的查询生成器,请参阅doctrine-project.org的QueryBuilder。
来试试,让我们暂时使用EventController里的indexAction。使用getRepository来获取UserRepository。请记住,你传递给getRepository的参数是entity的“快捷名称”:bundle名称加上Entity名称。
1 2 3 4 5 6 7 8 9 10 11 12 |
// src/Yoda/EventBundle/Controller/EventController.php // ... public function indexAction() { $em = $this->getDoctrine()->getManager(); // temporarily abuse this controller to see if this all works $userRepo = $em->getRepository('UserBundle:User'); // ... } |
现在,我们有UserRepository,让我们尝试新方法并dump结果:
1 2 3 4 5 6 7 8 |
public function indexAction() { // ... $userRepo = $em->getRepository('UserBundle:User'); var_dump($userRepo->findOneByUsernameOrEmail('user'));die; // ... } |
当我们刷新,我看到这个用户。如果我们想让email试试,我们要调整一下:
1 |
var_dump($userRepo->findOneByUsernameOrEmail('user@user.com'));die; |
酷!
我们以后会看到更多,在控制器中使用repository自带的方法来获取数据库对象。如果你需要一个特殊的查询,那就在你的repository中添加一个新的方法。