Nette Database
Nette Database é uma camada de banco de dados poderosa e elegante para PHP com ênfase na simplicidade e recursos inteligentes. Oferece duas formas de trabalhar com o banco de dados – Explorer para desenvolvimento rápido de aplicações, ou Acesso SQL para trabalho direto com consultas.
Acesso SQL
- Consultas parametrizadas seguras
- Controle preciso sobre a forma das consultas SQL
- Quando você escreve consultas complexas com recursos avançados
- Otimiza o desempenho usando funções SQL específicas
Explorer
- Desenvolve rapidamente sem escrever SQL
- Trabalho intuitivo com relações entre tabelas
- Você apreciará a otimização automática de consultas
- Adequado para trabalho rápido e confortável com o banco de dados
Instalação
A biblioteca pode ser baixada e instalada usando a ferramenta Composer:
composer require nette/database
Bancos de dados suportados
Nette Database suporta os seguintes bancos de dados:
Servidor de banco de dados | Nome DSN | Suporte no Explorer |
---|---|---|
MySQL (>= 5.1) | mysql | SIM |
PostgreSQL (>= 9.0) | pgsql | SIM |
Sqlite 3 (>= 3.8) | sqlite | SIM |
Oracle | oci | – |
MS SQL (PDO_SQLSRV) | sqlsrv | SIM |
MS SQL (PDO_DBLIB) | mssql | – |
ODBC | odbc | – |
Duas abordagens ao banco de dados
Nette Database oferece uma escolha: você pode escrever consultas SQL diretamente (acesso SQL) ou deixá-las serem geradas automaticamente (Explorer). Vejamos como ambas as abordagens resolvem as mesmas tarefas:
Acesso SQL – Consultas SQL
// inserção de registro
$database->query('INSERT INTO books', [
'author_id' => $authorId,
'title' => $bookData->title,
'published_at' => new DateTime,
]);
// obtenção de registros: autores de livros
$result = $database->query('
SELECT authors.*, COUNT(books.id) AS books_count
FROM authors
LEFT JOIN books ON authors.id = books.author_id
WHERE authors.active = 1
GROUP BY authors.id
');
// listagem (não otimizada, gera N consultas adicionais)
foreach ($result as $author) {
$books = $database->query('
SELECT * FROM books
WHERE author_id = ?
ORDER BY published_at DESC
', $author->id);
echo "Autor $author->name escreveu $author->books_count livros:\n";
foreach ($books as $book) {
echo "- $book->title\n";
}
}
Acesso Explorer – Geração automática de SQL
// inserção de registro
$database->table('books')->insert([
'author_id' => $authorId,
'title' => $bookData->title,
'published_at' => new DateTime,
]);
// obtenção de registros: autores de livros
$authors = $database->table('authors')
->where('active', 1);
// listagem (gera automaticamente apenas 2 consultas otimizadas)
foreach ($authors as $author) {
$books = $author->related('books')
->order('published_at DESC');
echo "Autor $author->name escreveu {$books->count()} livros:\n";
foreach ($books as $book) {
echo "- $book->title\n";
}
}
A abordagem Explorer gera e otimiza consultas SQL automaticamente. No exemplo fornecido, a abordagem SQL gera N+1 consultas (uma para os autores e depois uma para os livros de cada autor), enquanto o Explorer otimiza automaticamente as consultas e executa apenas duas – uma para os autores e uma para todos os seus livros.
Ambas as abordagens podem ser combinadas livremente na aplicação conforme necessário.
Conexão e configuração
Para conectar ao banco de dados, basta criar uma instância da classe Nette\Database\Connection:
$database = new Nette\Database\Connection($dsn, $user, $password);
O parâmetro $dsn
(data source name) é o mesmo que o PDO usa, por exemplo,
host=127.0.0.1;dbname=test
. Em caso de falha, lança a exceção Nette\Database\ConnectionException
.
No entanto, uma maneira mais conveniente é oferecida pela configuração da aplicação, onde basta adicionar a seção
database
e os objetos necessários serão criados, assim como o painel do banco de dados na barra Tracy.
database:
dsn: 'mysql:host=127.0.0.1;dbname=test'
user: root
password: password
Depois, o objeto de conexão pode ser obtido como um serviço do contêiner DI, por exemplo:
class Model
{
public function __construct(
// ou Nette\Database\Explorer
private Nette\Database\Connection $database,
) {
}
}
Mais informações sobre a configuração do banco de dados.
Criação manual do Explorer
Se você não usa o contêiner Nette DI, pode criar a instância Nette\Database\Explorer
manualmente:
// conexão com o banco de dados
$connection = new Nette\Database\Connection('mysql:host=127.0.0.1;dbname=mydatabase', 'user', 'password');
// armazenamento para cache, implementa Nette\Caching\Storage, por exemplo:
$storage = new Nette\Caching\Storages\FileStorage('/path/to/temp/dir');
// cuida da reflexão da estrutura do banco de dados
$structure = new Nette\Database\Structure($connection, $storage);
// define regras para mapear nomes de tabelas, colunas e chaves estrangeiras
$conventions = new Nette\Database\Conventions\DiscoveredConventions($structure);
$explorer = new Nette\Database\Explorer($connection, $structure, $conventions, $storage);
Gerenciamento de conexão
Ao criar o objeto Connection
, a conexão é estabelecida automaticamente. Se você deseja adiar a conexão, use
o modo lazy – ative-o na configuração definindo
lazy
como true
, ou assim:
$database = new Nette\Database\Connection($dsn, $user, $password, ['lazy' => true]);
Para gerenciar a conexão, use os métodos connect()
, disconnect()
e reconnect()
.
connect()
cria a conexão se ela ainda não existir, podendo lançar a exceçãoNette\Database\ConnectionException
.disconnect()
desconecta a conexão atual com o banco de dados.reconnect()
desconecta e, em seguida, reconecta ao banco de dados. Este método também pode lançar a exceçãoNette\Database\ConnectionException
.
Além disso, você pode monitorar eventos relacionados à conexão usando o evento onConnect
, que é um array de
callbacks chamados após o estabelecimento da conexão com o banco de dados.
// ocorre após a conexão com o banco de dados
$database->onConnect[] = function($database) {
echo "Conectado ao banco de dados";
};
Tracy Debug Bar
Se você usa Tracy, o painel Database é ativado automaticamente na Debug Bar, exibindo todas as consultas executadas, seus parâmetros, tempo de execução e o local no código onde foram chamadas.
