Projektowanie stron internetowych

Doctrine DBAL ( Doctrine Database Abstraction Layer ) w Symfony2

Czasami zachodzi potrzeba wykonania zapytania do bazy bez użycia ORM’a. Jest to przydatne zwłaszcza wtedy gdy ORM tak przekombinuje zapytanie, że silnik bazodanowy sobie z nim nie poradzi i zwróci błąd. Podczas pracy z silnikiem bazodanowym Mssql często miałem problem gdy musiałem tworzyć podzapytania oraz gdy używałem metody setMaxResults() ograniczającej w zapytaniu liczbę wyników kończyło się to błędem po stronie silnika bazodanowego.

Wpierw powinniśmy sprawdzić jak wygląda nasza konfiguracja połączenia z bazą danych. Konfiguracje możemy sprawdzić w pliku app/config/config.yml

doctrine:
    dbal:
        driver:   pdo_mysql
        dbname:   nazwabazy
        user:     nazwauzytkownika
        password: haslouzytkownika

Dostęp do połączenia DBAL otrzymujemy za pomocą usługi database_connection 

class TestController extends Controller
{
    public function indexAction()
    {
        $conn = $this->get('database_connection');
        $rows = $conn->fetchAll('SELECT * FROM stany');
        // ...
    }
}

Jeśli mamy skonfigurowanych kilka połączeń w pliku app/config/config.yml

doctrine:
    dbal:
        default_connection:   user
        connections:
            user:
                driver:   "%database_driver%"
                host:     "%database_host%"
                path:     "%database_path%"
                user:     "%database_user%"
                password: "%database_password%"
                charset:  UTF8
            prolider_sim:
                driver_class:   PDODblibBundle\Doctrine\DBAL\Driver\PDODblib\Driver
                driver:   "%database_driver2%"
                host:     "%database_host2%"
                port:     "%database_port2%"
                dbname:   "%database_name2%"
                user:     "%database_user2%"
                password: "%database_password2%"
                charset:  UTF8

Usługa database_connection  będzie się odwoływać do domyslnego połączenia ustawionego w parametrze default_connection.

Oczywiście Każde połączenie jest również dostępne za pomocą usługi

doctrine.dbal.[nazwa_połączenia]_connection

Przykładowe wykorzystanie usługi innego połączenia niż domyślne może wyglądać tak:

class TestMultipleConnController extends Controller
{
    public function indexAction()
    {
        $conn = $this->container->get('doctrine.dbal.prolider_fk_connection');
        $rows = $conn->fetchAll('SELECT * FROM stany');
        // ...
    }
}

Minusem jest to że nie mamy odseparowanej warstwy modelu od kontrolera, jednak jeśli nie możemy sobie poradzić z ORM’em to jest to kompromisowe rozwiązanie naszego problemu.