zoukankan      html  css  js  c++  java
  • laravel-5-doctrine-2 教程

    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
    LaravelDoctrineORMDoctrineServiceProvider::class,

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

    1
    2
    3
    'EntityManager' => LaravelDoctrineORMFacadesEntityManager::class,
    'Registry' => LaravelDoctrineORMFacadesRegistry::class,
    'Doctrine' => LaravelDoctrineORMFacadesDoctrine::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 AppDomain:

    We change:

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

    For:

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

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

    Change:

    1
    2
    3
    'custom_types' => [
     'json' => LaravelDoctrineORMTypesJson::class,
     ],

    To:

    1
    2
    3
    4
    'custom_types' => [
     'json' => LaravelDoctrineORMTypesJson::class,
     'uuid' => RamseyUuidDoctrineUuidType::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:

    Selection_076

    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 AppDomainTeacher;
     
    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 RamseyUuidDoctrineUuidGenerator;
     
    return [
        'AppDomainTeacherTeacher' => [
            '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 = RamseyUuidUuid::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:

    Selection_077

    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 AppDomainTeacher;
     
    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 AppDomainTeacherTeacherRepository;
    use AppDomainTeacherTeacher;
     
    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:

    Selection_078

    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 AppInfrastructure;
     
    use DoctrineORMEntityRepository;
    use DoctrineCommonUtilInflector;
     
    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:

    Selection_079

    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 AppInfrastructureTeacher;
     
    use AppDomainTeacherTeacherRepository;
    use AppInfrastructureDoctrineBaseRepository;
     
    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(AppDomainTeacherTeacherRepository::class, function($app) {
                // This is what Doctrine's EntityRepository needs in its constructor.
                return new AppInfrastructureTeacherDoctrineTeacherRepository(
                    $app['em'],
                    $app['em']->getClassMetaData(AppDomainTeacherTeacher::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:

    Selection_080


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

  • 相关阅读:
    [BJOI2019] 光线
    C# 从零开始写 SharpDx 应用 笔刷
    BAT 脚本判断当前系统是 x86 还是 x64 系统
    BAT 脚本判断当前系统是 x86 还是 x64 系统
    win2d 通过 CanvasActiveLayer 画出透明度和裁剪
    win2d 通过 CanvasActiveLayer 画出透明度和裁剪
    PowerShell 拿到显卡信息
    PowerShell 拿到显卡信息
    win10 uwp 如何使用DataTemplate
    win10 uwp 如何使用DataTemplate
  • 原文地址:https://www.cnblogs.com/yingjie13/p/7911853.html
Copyright © 2011-2022 走看看