This presentation was given at the Laravel Austin meetup April 5th, 2018. We took a dive into what Doctrine is, how it works and how it is different from Eloquent.
to a set of columns in a database table. This object will not be mapped to a table by itself, but will be used inside an entity, so its columns will be mapped to the entity's table instead. Doctrine 2 — Laravel Austin 10
{ /** * One Product has Many Features. * @OneToMany(targetEntity="Feature", mappedBy="product") */ private $features; } /** @Entity */ class Feature { /** * Many Features have One Product. * @ManyToOne(targetEntity="Product", inversedBy="features") * @JoinColumn(name="product_id", referencedColumnName="id") */ private $product; } 22
* One Category has Many Categories. * @OneToMany(targetEntity="Category", mappedBy="parent") */ private $children; /** * Many Categories have One Category. * @ManyToOne(targetEntity="Category", inversedBy="children") * @JoinColumn(name="parent_id", referencedColumnName="id") */ private $parent; } 24
* Many Users have Many Groups. * @ManyToMany(targetEntity="Group", inversedBy="users") * @JoinTable(name="users_groups") */ private $groups; } /** @Entity */ class Group { /** * Many Groups have Many Users. * @ManyToMany(targetEntity="User", mappedBy="groups") */ private $users; } 26
implements ScientistRepository { // public function find($id) already implemented in parent class! public function findByName($name) { return $this->findBy(['name' => $name]); } } // Then, in one of your ServiceProviders use App\Research\Scientist; class AppServiceProvider { public function register() { $this->app->bind(ScientistRepository::class, function($app) { // This is what Doctrine's EntityRepository needs in its constructor. return new DoctrineScientistRepository( $app['em'], $app['em']->getClassMetaData(Scientist::class) ); }); } } 35
{ private $genericRepository; public function __construct(ObjectRepository $genericRepository) { $this->genericRepository = $genericRepository; } public function find($id) { return $this->genericRepository->find($id); } public function findByName($name) { return $this->genericRepository->findBy(['name' => $name]); } } // Then, in one of your ServiceProviders use App\Research\Scientist; class AppServiceProvider { public function register() { $this->app->bind(ScientistRepository::class, function(){ return new DoctrineScientistRepository( EntityManager::getRepository(Scientist::class) ); }); } } 36
Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity(repositoryClass="MyDomain\Model\UserRepository") */ class User { } class UserRepository extends EntityRepository { public function getAllAdminUsers() { return $this->em->createQuery('SELECT u FROM MyDomain\Model\User u WHERE u.status = "admin"') ->getResult(); } } $admins = $em->getRepository('MyDomain\Model\User')->getAllAdminUsers(); Doctrine 2 — Laravel Austin 37
u.address a WHERE a.city = 'Berlin'"); $query = $em->createQuery("SELECT u, a FROM User u JOIN u.address a WHERE a.city = 'Berlin'"); $users = $query->getResult(); http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html 40
User u join u.address a WHERE u.name = ?1" // User owns association to an Address and the Address is loaded in the query. $rsm = new ResultSetMapping; $rsm->addEntityResult('User', 'u'); $rsm->addFieldResult('u', 'id', 'id'); $rsm->addFieldResult('u', 'name', 'name'); $rsm->addJoinedEntityResult('Address' , 'a', 'u', 'address'); $rsm->addFieldResult('a', 'address_id', 'id'); $rsm->addFieldResult('a', 'street', 'street'); $rsm->addFieldResult('a', 'city', 'city'); $sql = 'SELECT u.id, u.name, a.id AS address_id, a.street, a.city FROM users u ' . 'INNER JOIN address a ON u.address_id = a.id WHERE u.name = ?'; $query = $this->em->createNativeQuery($sql, $rsm); $query->setParameter(1, 'romanb'); $users = $query->getResult(); http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/native-sql.html 44