The final Countdown
Kommentare

Verbindung zur Datenbank
Eines der wichtigsten Designziele für FLOW3 war es, dass sich der Programmierer voll und ganz auf die Geschäftslogik konzentrieren und Infrastruktur wie Templating oder eben

Verbindung zur Datenbank

Eines der wichtigsten Designziele für FLOW3 war es, dass sich der Programmierer voll und ganz auf die Geschäftslogik konzentrieren und Infrastruktur wie Templating oder eben auch Datanbankzugriff völlig ignorieren kann. Das wird auch als Infrastructure Ignorance bezeichnet und ist eine der Säulen im Domain-driven Design (DDD). Folgerichtig merkt der Entwickler auch nichts mehr von der Datenbank, sobald er sie einmal eingerichtet hat. So wird kein SQL-Code geschrieben und selbst der Zugriff auf die in der Datenbank gespeicherten Daten erfolgt meist völlig automatisch und transparent an den benötigten Stellen. Bevor die Datenbank aber einsatzfähig ist, muss sie konfiguriert werden. Dafür kopiert man sich die Datei Configuration/Settings.yaml. example in Configuration/Settings.yaml um und editiert sie:

TYPO3:
  FLOW3:
    persistence:
      backendOptions:
        driver: 'pdo_mysql'
        dbname: 'flow3' 		# Datenbank-Name
        user: 'root'         	# Datenbank-User
        password: 'password' 	# Datenbank-Passwort
        host: '127.0.0.1'    	# Datenbank-Host
        port: '3306'		# Datenbank-Port

 In dieser YAML-Konfigurationsdatei [6] werden nun die Zugangsdaten für die MySQL-Datenbank eingetragen, die vorher schon existieren muss. Zuletzt muss das in FLOW3 integrierte Doctrine2-Framework angewiesen werden, die benötigte Datenbankstruktur aufzubauen:

$ ./flow3 doctrine:migrate
Migrating up to 20110824124935 from 0
  ++ migrating 20110613223837
  ...
  ++ finished in 0.47
  ++ 5 migrations executed
  ++ 28 sql queries
Speichern von Objekten

Mithilfe des Kickstarters können wir nun auch ein Domänenobjekt samt zugehörigem Controller, Repository (Zugriffseinheit für den Datenzugriff) und Templates für den CRUD-Prozess (Create, Read, Update, Delete) sowie ein Default-Layout (das von jedem Template geladen wird) anlegen lassen. Da ich genauso wie die FLOW3-Chefarchitekten kaffeesüchtig bin, verwende ich hier natürlich als Domänenobjekt die CoffeeBean (Listing 2), (Abb. 2). Sobald man ein neues Modell erstellt oder ein bereits erstelltes verändert, muss die Datenbankstruktur entsprechend angepasst werden. Das kann über die doctrine:update-Funktion in der Kommandozeile erledigt werden:

Listing 2
  $ ./flow3 kickstart:actioncontroller --generate-actions --generate-related Acme.Demo CoffeeBean
Created .../Acme.Demo/Classes/Domain/Model/CoffeeBean.php
Created .../Acme.Demo/Classes/Domain/Repository/CoffeeBeanRepository.php
Created .../Acme.Demo/Classes/Controller/CoffeeBeanController.php
Created .../Acme.Demo/Resources/Private/Layouts/Default.html
Created .../Acme.Demo/Resources/Private/Templates/CoffeeBean/Index.html
Created .../Acme.Demo/Resources/Private/Templates/CoffeeBean/New.html
Created .../Acme.Demo/Resources/Private/Templates/CoffeeBean/Edit.html
Created .../Acme.Demo/Resources/Private/Templates/CoffeeBean/Show.html


$ ./flow3 doctrine:update
Executed a database schema update.

Der Aufruf zum Anlegen und Verwalten von CoffeBeans geht nun analog: http://flow3/Acme.Demo/CoffeeBean/.

Abb. 2: Der CRUD-Prozess für das Domänenobjekt CoffeeBean
Analyse des Codes

Schauen wir uns nun den erhaltenen Code des Modells (CoffeeBean.php) und des Controllers (CoffeeBeanController.php) etwas genauer an, um zu verstehen, was unter der Haube von FLOW3 vor sich geht (Listing 3). Das Domänenobjekt CoffeeBean ist gemäß DDD eine Entity [7] (das wird durch die Annotation @entity gekennzeichnet) und besitzt die Eigenschaft name, die (wie im Übrigen alle Properties in FLOW3) als protected gekennzeichnet ist. Daher benötigt es öffentliche Getter und Setter, die ebenfalls mit erzeugt wurden. Sämtliche Zugriffe (schreibend und lesend) auf die Eigenschaften erfolgen innerhalb von FLOW3 und Fluid ausschließlich über diese Funktionen. So ist der Code des erzeugten Controllers schon etwas umfangreicher (Listing 4).

Listing 3
name;
        }

        /**
         * Sets this Coffee bean's name
         *
         * @param string $name The Coffee bean's name
         * @return void
         */
        public function setName($name) {
                $this->name = $name;
        }
}
?>
Listing 4
view->assign('coffeeBeans', $this->coffeeBeanRepository->findAll());
        }

        /**
         * Shows a single coffee bean object
         *
         * @param AcmeDemoDomainModelCoffeeBean $coffeeBean The coffee bean to show
         */
        public function showAction(CoffeeBean $coffeeBean) {
                $this->view->assign('coffeeBean', $coffeeBean);
        }

        /**
         * Shows a form for creating a new coffee bean object
         */
        public function newAction() {
        }

        /**
         * Adds the given new coffee bean object to the coffee bean repository
         *
         * @param AcmeDemoDomainModelCoffeeBean $coffeeBean A new coffee bean to add
         */
        public function createAction(CoffeeBean $newCoffeeBean) {
                $this->coffeeBeanRepository->add($newCoffeeBean);
                $this->flashMessageContainer->add('Created a new coffee bean.');
                $this->redirect('index');
        }

        /**
         * Shows a form for editing an existing coffee bean object
         *
         * @param AcmeDemoDomainModelCoffeeBean $coffeeBean The coffee bean to edit
         */
        public function editAction(CoffeeBean $coffeeBean) {
                $this->view->assign('coffeeBean', $coffeeBean);
        }

        /**
         * Updates the given coffee bean object
         *
         * @param AcmeDemoDomainModelCoffeeBean $coffeeBean The coffee bean to update
         */
        public function updateAction(CoffeeBean $coffeeBean) {
                $this->coffeeBeanRepository->update($coffeeBean);
                $this->flashMessageContainer->add('Updated the coffee bean.');
                $this->redirect('index');
        }

        /**
         * Removes the given coffee bean object from the coffee bean repository
         *
         * @param AcmeDemoDomainModelCoffeeBean $coffeeBean The coffee bean to delete
         */
        public function deleteAction(CoffeeBean $coffeeBean) {
                $this->coffeeBeanRepository->remove($coffeeBean);
                $this->flashMessageContainer->add('Deleted a coffee bean.');
                $this->redirect('index');
        }

}

?>
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -