Open up a Terminal again, cd into learning folder and run:

composer require "laravel-doctrine/orm:1.1.*"

Likewise, install uuid-doctrine:

composer require ramsey/uuid-doctrine

Open config/app.php file and add into providers array the following line:

1
LaravelDoctrine\ORM\DoctrineServiceProvider::class,

In the same file, look for aliases array and add the following lines:

1
2
3
'EntityManager' => LaravelDoctrine\ORM\Facades\EntityManager::class,
'Registry' => LaravelDoctrine\ORM\Facades\Registry::class,
'Doctrine' => LaravelDoctrine\ORM\Facades\Doctrine::class,

Once you have added it, open up a terminal and run the following command to publish configuration above:

php artisan vendor:publish --tag="config"

Doctrine configuration

The config/doctrine.php file must be to modified as follows:

We edit the line:

1
 'meta' => env('DOCTRINE_METADATA', 'annotations'),

For:

1
'meta' => env('DOCTRINE_METADATA', 'config'),

In this line, we are changing the way to map the entities, of annotations to configuration files (congif). There are several ways to map our entities with the tables in the database (annotations, yaml, xml, configuration files, static function in the entities), we chose configuration files because in this way, the definition of metadatas is separated of the entities and it adapts better configuration files used by Laravel.

Then, place the ‘mapping_file’ item below the ‘connection’ item, as follows:

1
2
3
'connection' => env('DB_CONNECTION', 'mysql'),
 'mapping_file' => 'mappings',
 'namespaces' => [

With this, we are saying that the object-relational mapping config file will be called: mappings.php.

Then,  to prevent that Doctrine searches the entities throughout the app folder, set the namespace where it will search, in this case App\Domain:

We change:

1
2
3
'namespaces' => [
'App'
],

For:

1
2
3
'namespaces' => [
'App\Domain'
],

Finally, in the same file, add the data type uuid for Doctrine

Change:

1
2
3
'custom_types' => [
 'json' => LaravelDoctrine\ORM\Types\Json::class,
 ],

To:

1
2
3
4
'custom_types' => [
 'json' => LaravelDoctrine\ORM\Types\Json::class,
 'uuid' => Ramsey\Uuid\Doctrine\UuidType::class
 ],

Working with Domain

Inside app/ directory, create a new folder called Domain and into this, create another folder calledTeacher, in this folder, create the Teacher.php file which will contain the Teacher entity, as shown in the picture:

The Teacher entity will have the attributes: $id and $name, in addition, it will contain the setters and getters methods, additionally it will contain a whitelist() method which will return an array of attributes which can be assigned, as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
namespace App\Domain\Teacher;
 
class Teacher
{
    protected $id;
 
    protected $name;
 
    public function getId()
    {
        return $this->id;
    }
  
    public function getName()
    {
        return $this->name;
    }
  
    public function setName($name)
    {
        $this->name = $name;
    }
 
    public function whitelist()
    {
        return [
            'name'
        ];
    }
}

Mapping the entity with the table

Now, we must map the entity, for that, create the config/mappings.php and put the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
use Ramsey\Uuid\Doctrine\UuidGenerator;
 
return [
    'App\Domain\Teacher\Teacher' => [
        'type'   => 'entity',
        'table'  => 'teachers',
        'id'     => [
            'id' => [
                'type'     => 'uuid',
                'generator' => [
                    'strategy' => 'custom'
                ],
                'customIdGenerator' => [
                    'class' => UuidGenerator::class
                ],
            ],
        ],
        'fields' => [
            'name' => [
                'type' => 'string'
            ]
        ]
    ]
];

With this, Doctrine will know that the Teacher class  will be recorded in the teachers table, and this will have an identifier field called id which will be generate through the UuidGenerator class (we also can generate this id if we create a constructor in the entity and inside it we put $this->id = Ramsey\Uuid\Uuid::uuid4() ) and the name field of type string.

Creating the database

On the mysql command line, create a empty database called learning:

create database learning;

We can do it using phpmyadmin or another mysql client.

Database Configuration

Edit the following fields into the Laravel config file .env according your local database settings:

1
2
3
4
DB_HOST=127.0.0.1
DB_DATABASE=learning
DB_USERNAME=root
DB_PASSWORD=123456

Run the following command to create the teachers table in the database through the mapping scheme:

php artisan doctrine:schema:create

Repository Interface

Now, let’s create the TeacherRepository.php file in app/Domain/Teacher as shown in the picture:

In this file we will create the TeacherRepository interface, which will have the methods: create,updatesavedeletefind y findAll, those methods will be implemented after using Doctrine.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
namespace App\Domain\Teacher;
 
interface TeacherRepository
{
    public function create($data);
 
    public function update($data, $id);
 
    public function save($object);
 
    public function delete($object);
 
    public function find($id);
 
    public function findAll();
}

Testing

Let’s create a test class using the Laravel artisan command:

php artisan make:test TeacherRepositoryTest

This command will create us the TeacherRepositoryTest.php in /test folder, in this file we will test methods of the repository, as shown in the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php
 
use App\Domain\Teacher\TeacherRepository;
use App\Domain\Teacher\Teacher;
 
class TeacherRepositoryTest extends TestCase
{
    protected $repository;
 
    protected static $teacher;
     
    public function setUp()
    {
        parent::setUp();
 
        $this->repository = App::make(TeacherRepository::class);
    }
 
    public function testCreateAndSave()
    {
        $data = array(
            'name' => 'foo'
            );
 
        $teacher = $this->repository->create($data);
 
        self::$teacher = $this->repository->save($teacher);
 
        $this->seeInDatabase('teachers',['id'=>self::$teacher->getId()]);
    }
 
    public function testUpdateAndSave()
    {
        $data = array(
            'name' => 'bar'
            );
 
        $teacher = $this->repository->update($data, self::$teacher->getId());
 
        self::$teacher = $this->repository->save($teacher);
 
        $this->assertEquals($data['name'],self::$teacher->getName());
    }
 
    public function testFindAll()
    {
        $teachers = $this->repository->findAll();
 
        $this->assertContainsOnlyInstancesOf(Teacher::class, $teachers);
    }
 
    public function testDelete()
    {
        $teacher = $this->repository->find(self::$teacher->getId());
 
        $result = $this->repository->delete($teacher);
 
        $this->assertTrue($result);
    }
 
}

Doctrine Implementation

Create Infrastructure folder into app/ folder and into this folder create DoctrineBaseRepository.php file, as shown below:

In this file let’s create the DoctrineBaseRepository class, which extends of EntityRepository class of Doctrine. DoctrineBaseRepository will have the common and necessary methods which all the next repositories will have.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?php
namespace App\Infrastructure;
 
use Doctrine\ORM\EntityRepository;
use Doctrine\Common\Util\Inflector;
 
class DoctrineBaseRepository extends EntityRepository
{
    public function create($data)
    {
        $entity = new $this->_entityName();
 
        return $this->prepare($entity, $data);
 
    }
 
    public function update($data, $id)
    {
        $entity = $this->find($id);
 
        return $this->prepare($entity, $data);
    }
 
    public function prepare($entity, $data)
    {
        $set = 'set';
        $whitelist = $entity->whitelist();
         
        foreach($whitelist as $field){
 
            if (isset($data[$field])){
                $setter = $set.Inflector::classify($field);
                $entity->$setter($data[$field]);
            }
 
        }
 
        return $entity;
    }    
 
    public function save($object)
    {
        $this->_em->persist($object);
 
        $this->_em->flush($object);
 
        return $object;
    }
 
    public function delete($object)
    {
        $this->_em->remove($object);
 
        $this->_em->flush($object);
 
        return true;
    }
}

The methods create() and update() create and update respectively the object by assigning its attributes through the method prepare() and the methods save() and delete() as their names imply, persist and remove those objects in the database.

Then, into the app/Infrastructure let’s create the Teacher folder and inside it let’s create the DoctrineTeacherRepository.php file, as shown in the following image:

In this file will be the DoctrineTeacherRepository class which will be the repository of persistence and recovery of data from the Teacher entity, this will extend the previouslyDoctrineBaseRepository class created to inherit all the basic and necessary methods and it will implement the TeacherRepository interface. Here you can add any other particular method that business logic required, for now we won’t need any other and we will leave it without additional methods:

1
2
3
4
5
6
7
8
9
<?php
namespace App\Infrastructure\Teacher;
 
use App\Domain\Teacher\TeacherRepository;
use App\Infrastructure\DoctrineBaseRepository;
 
class DoctrineTeacherRepository extends DoctrineBaseRepository implements TeacherRepository
{
}

Let’s open the app/Providers/AppServiceProvider.php file and into the register() method add the code which will instance DoctrineTeacherRepository class when the TeacherRepository interface is used.

1
2
3
4
5
6
7
8
9
10
    public function register()
    {
        $this->app->bind(\App\Domain\Teacher\TeacherRepository::class, function($app) {
            // This is what Doctrine's EntityRepository needs in its constructor.
            return new \App\Infrastructure\Teacher\DoctrineTeacherRepository(
                $app['em'],
                $app['em']->getClassMetaData(\App\Domain\Teacher\Teacher::class)
            );
        });
    }

Testing the repository

With this we can use the repository created.

To test if it works, let’s use the TeacherRepositoryTest class made earlier, running the command:

vendor/bin/phpunit

We should get the following answer:

This tells us that through the repository we were able to create, update, view and delete a record in the database.

laravel-5-doctrine-2 教程的更多相关文章

  1. Laravel大型项目系列教程(三)之发表文章

    Laravel大型项目系列教程(三)之发表文章 一.前言 上一节教程中完成了用户管理,这节教程将大概完成发表Markdown格式文章并展示的功能. 二.Let's go 1.数据库迁移 文章模块中我们 ...

  2. Laravel大型项目系列教程(二)之用户管理

    Laravel大型项目系列教程(二) 一.前言 本节教程将大概实现用户的注册.修改个人信息.管理用户功能. 二.Let's go 1.创建用户注册视图 $ php artisan generate:v ...

  3. Laravel大型项目系列教程(一)

    Laravel大型项目系列教程(一) 一.课程概述 1.课程介绍 本教程将使用Laravel完成一个多用户的博客系统,大概会包含如下内容: 路由管理. 用户管理,如用户注册.修改信息.锁定用户等. 文 ...

  4. Laravel 5 系列入门教程(一)【最适合中国人的 Laravel 教程】

    Laravel 5 系列入门教程(一)[最适合中国人的 Laravel 教程] 分享⋅ johnlui⋅ 于 2年前 ⋅ 最后回复由 skys215于 11个月前 ⋅ 17543 阅读   原文发表在 ...

  5. Laravel 4 系列入门教程(一)

    默认条件 本文默认你已经有配置完善的PHP+MySQL运行环境,懂得PHP网站运行的基础知识.跟随本教程走完一遍,你将会得到一个基础的包含登录的简单blog系统,并将学会如何使用一些强大的Larave ...

  6. Laravel大型项目系列教程(四)显示文章列表和用户修改文章

    小编心语:不知不觉已经第四部分了,非常感谢很多人给小编提的意见,改了很多bug,希望以后能继续帮小编找找茬~小编也不希望误导大家~这一节,主要讲的 是如何显示文章列表和让用户修改文章,小编预告一下(一 ...

  7. Homestead 安装 phpMyAdmin 作为数据库管理客户端 — Laravel 实战 iBrand API 教程

    简介 phpMyAdmin 是一个以PHP为基础,以Web-Base方式架构在网站主机上的MySQL的数据库管理工具,让管理者可用Web接口管理MySQL数据库.借由此Web接口可以成为一个简易方式输 ...

  8. Laravel Class 'Doctrine\DBAL\Driver\PDOMySql\Driver' not found

    Laravel: 5.5.* 在迁移中有重命名操作的时候,运行 php artisan migrate 会提示 Class 'Doctrine\DBAL\Driver\PDOMySql\Driver' ...

  9. Laravel大型项目系列教程(五)之文章和标签管理

    一.前言 本节教程将大概完成文章和标签管理以及标签关联. 二.Let's go 1.文章管理 首先创建管理后台文章列表视图: $ php artisan generate:view admin.art ...

  10. laravel框架session使用教程

    laravel是一款php框架了,在使用laravel时会碰到session使用问题了,在使用过程中碰到一些问题与一些应用的例子. 用Laravel开发应用,把原有的代码copy过来,以前的代码ses ...

随机推荐

  1. Light Table 编辑器修改字体 更新

    view->command->use.behaviors 加上这一句  (:lt.objs.style/font-settings "Inconsolata" 14 1 ...

  2. IE浏览器报Promise未定义

    用vue-cli做的项目,用了promise,结果IE下报promise未定义,甚至在比较老的andriod手机浏览器上会显示空白页面,解决方案如下: 首先安装:babel-polyfill npm ...

  3. Android和kernel杂散点集合

    Android: 1.编译 普通的编译: 1). source build/envsetup.sh 2).lunch 3).make -jx make kernel:只重新编译kernel部分镜像,但 ...

  4. 架构实战项目心得(七):使用SpringBoot+Dubbo+Mybatisplus+Oracle搭建后台项目框架(二)

    接下来我们将整合mybatisplus+Oracle,实现一个简单的查询.(期间踩了很多坑,遇到一些问题,还好慢慢解决了.现在是通过配置文件的方式来进行dubbo服务的注册和发布,希望以后能在学习和实 ...

  5. 原创经验:微信小程序开发总结

    学习时间不短了.今天公司不加班总结一下我的开发经验吧,以下都是我认为很重要的总结哦!写下来让我自己也记得更清楚,同时希望可以帮助到有需要的同学哦 一: 参数传值的方法 1:  data-id我们可以给 ...

  6. isPrototypeOf、instanceof、hasOwnProperty函数整理

    isPrototypeOf 作用:检测一个对象是否是另一个对象的原型.或者说一个对象是否被包含在另一个对象的原型链中 var p = {x:1};//定义一个原型对象 var o = Object.c ...

  7. Windows 10 搭建Hadoop平台

    一.环境配置 JDK:1.8. Hadoop下载地址(我选择的是2.7.6版本):https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/ ...

  8. 十三、nginx 强制下载txt等文件

    当前的浏览器能够识别文件格式,如果浏览器本身能够解析就会默认打开,如果不能解析就会下载该文件. 那么使用nginx做资源服务器的时候,如何强制下载文件呢? location /back/upload/ ...

  9. Java API 之 Annotation功能

    JDK1.5开始增加了Annotation功能,该功能可用于: 1.类: 2.构造方法: 3.成员变量: 4.方法 5.参数 等的声明: 该功能并不影响程序的运行,但是会对编译器警告等辅助工具产生影响 ...

  10. java温故而知新(9)OOP(面向对象编程)理念

    Object   Oriented   Programming   (面向对象的程序设计) 1.定义 面向对象程序设计(OOP)的具体定义很难下,也很容易因此而引起争论,在   Object-Orie ...