Novatec Editora Ltda. [2014].



Documentos relacionados
Novatec Editora Ltda. [2014].

Pete Goodliffe. Novatec

Manipulação de Banco de Dados com Java. Ms. Bruno Crestani Calegaro Maio/ 2015

Persistência de dados com JPA. Hélder Antero Amaral Nunes

Desenvolvendo Websites com PHP

JPA: Persistência padronizada em Java

Manipulação de Banco de Dados com Java 1. Objetivos

Parte I. Demoiselle Mail

HIBERNATE EM APLICAÇÃO JAVA WEB

Jonathan Stark Brian Jepson

Persistência de Classes em Tabelas de Banco de Dados

Leonardo Gresta Paulino Murta

Manual SAGe Versão 1.2 (a partir da versão )

UFG - Instituto de Informática

Desenvolvendo Websites com PHP

UFG - Instituto de Informática

JDBC Java Database Connectivity

Orientação a Objetos

Listando itens em ComboBox e gravando os dados no Banco de Dados MySQL.

Wilson Moraes Góes. Novatec

David Hows Peter Membrey Eelco Plugge

Procedimentos para Reinstalação do Sisloc

JDBC (Java Database Connectivity) Padrão de Projeto DAO (Data Access Object) Roteiro para instalação do banco de dados e do driver JDBC

Android e Bancos de Dados

Aula 1 Acesso a Banco de Dados

Google Android para Tablets

02 - Usando o SiteMaster - Informações importantes

Laboratório de Banco de Dados Aula 1 Acesso a Banco de Dados. Prof. Josenildo Silva jcsilva@ifma.edu.br

JDBC. Siga as instruções para instalar o banco de dados H2 e criar a tabela Alunos.

Introdução a Banco de Dados

Acesso a Banco. Conexão em Java. Conexão em Java. Programação Orientada a Objetos Profa. Cristiane e Prof. Daniel

Crie Seu Próprio Site

Persistência de Dados

Capture Pro Software. Guia de referência. A-61640_pt-br

ArpPrintServer. Sistema de Gerenciamento de Impressão By Netsource Rev: 02

Entendendo como funciona o NAT

MDaemon GroupWare. Versão 1 Manual do Usuário. plugin para o Microsoft Outlook. Trabalhe em Equipe Usando o Outlook e o MDaemon

marketing ágil Utilização de Metodologias Ágeis em Projetos de Marketing Michelle Accardi-Petersen Novatec

ATRIBUTOS PRIVADOS 6. ENCAPSULAMENTO MÉTODOS PRIVADOS MÉTODOS PRIVADOS

JDBC. Prof. Márcio Bueno

Ricardo R. Lecheta. Novatec

Configurando um Grupo Doméstico e Compartilhando arquivos no Windows 7

Design Centrado no Usuário

Follow-Up Acompanhamento Eletrônico de Processos (versão 3.0) Manual do Sistema. 1. Como acessar o sistema Requisitos mínimos e compatibilidade

Construindo Sites com. CSS e (X)HTML. sites controlados por folhas de estilo em cascata. Maurício Samy Silva. Novatec

Banco de Dados. Sérgio Luiz Ruivace Cerqueira

NOVIDADES DO JAVA PARA PROGRAMADORES C

UNIVERSIDADE FEDERAL DO RIO GRANDE DO NORTE ESCOLA AGRÍCOLA DE JUNDIAÍ EAJ - PRONATEC / REDE etec MÓDULO III DESENVOLVIMENTO PROFESSOR ADDSON COSTA

Padrões de Projeto em PHP

Google Drive: Acesse e organize seus arquivos

edirectory Plataforma ios / Android

Google Drive. Passos. Configurando o Google Drive

Curso de Java. Acesso a banco de dados através do Hibernate. Todos os direitos reservados Klais

Desenvolvendo plugins WordPress usando Orientação a Objetos

INSTRUMENTO NORMATIVO 004 IN004

Banco de Dados. Banco de Dados. Alcides Pamplona Alcides Pamplona Linguagem de Programação CESBD 2010

Guia de administração para a integração do Portrait Dialogue 6.0. Versão 7.0A

Microsoft Access XP Módulo Um

Facebook Instruções de integração com PayPal

SUMÁRIO 1. AULA 6 ENDEREÇAMENTO IP:... 2

Análise e Desenvolvimento de Sistemas ADS Programação Orientada a Obejeto POO 3º Semestre AULA 03 - INTRODUÇÃO À PROGRAMAÇÃO ORIENTADA A OBJETO (POO)

Programação Orientada a Objetos com PHP & MySQL Sistema Gerenciador de Banco de Dados: Introdução e configuração de bases de dados com Postgre e MySQL

8. Outros tipos de Transação (Modo de Transação de Autoconfirmação e Modo Implícito)

Manual do Painel Administrativo

Principais Comandos SQL Usados no MySql

APOSTILA BANCO DE DADOS INTRODUÇÃO A LINGUAGEM SQL

1 Criar uma entity a partir de uma web application que usa a Framework JavaServer Faces (JSF)

Josh Pauli Revisão técnica Scott White. Novatec


Criando um script simples

DOCUMENTAÇÃO DO FRAMEWORK - versão 2.0

FileMaker Pro 13. Utilização de uma Conexão de Área de Trabalho Remota com o FileMaker Pro 13

Barra de ferramentas padrão. Barra de formatação. Barra de desenho Painel de Tarefas

3. No painel da direita, dê um clique com o botão direito do mouse em qualquer espaço livre (área em branco).

Sumário INTRODUÇÃO Acesso ao Ambiente do Aluno Ferramentas e Configurações Ver Perfil Modificar Perfil...

Operador de Computador. Informática Básica

Computadores XXI: Busca e execução Final

Instalando servidor Apache com MySQL e as linguagens ColdFusion e PHP. XAMPP (xampp-win installer.exe), veja aqui.

Lição 1 - Criação de campos calculados em consultas

Programação com Acesso a Banco de Dados

Trabalhando com conexão ao banco de dados MySQL no Lazarus. Prof. Vitor H. Migoto de Gouvêa Colégio IDESA 2011

Demoiselle Report Guide. Demoiselle Report. Marlon Carvalho. Rodrigo Hjort. Robson Ximenes

Anote aqui as informações necessárias:

Prevayler. Perola. André Luís Sales de Moraes Juliana Keiko Yamaguchi Tatiana Yuka Takaki

GUIA DE CONSULTA RÁPIDA PARA. Instalação do Nokia Connectivity Cable Drivers

Ricardo Lino Olonca. Novatec

Programação Orientada a Objetos com PHP & MySQL Cookies e Sessões. Prof. MSc. Hugo Souza

Feature-Driven Development

Manual AGENDA DE BACKUP

SISTEMAS OPERACIONAIS ABERTOS Prof. Ricardo Rodrigues Barcelar

Pramod J. Sadalage Martin Fowler

DocuWare Mobile ProductInfo. Gerenciamento móvel de documentos. Benefícios

OCOMON PRIMEIROS PASSOS

CRIANDO BANCOS DE DADOS NO SQL SERVER 2008 R2 COM O SQL SERVER MANAGEMENT STUDIO

OMT-G Design. Instalação por pacotes

Atalhos da Web. Krishna Tateneni Yves Arrouye Tradução: Lisiane Sztoltz

Java com Banco de Dados Posgree

As Leis Fundamentais do Projeto de Software

Transcrição:

Novatec

Authorized Portuguese translation of the English edition of Just Hibernate, ISBN 9781449334376 2014 Madhusudhan Konda. This translation is published and sold by permission of O'Reilly Media, Inc., which owns or controls all rights to publish and sell the same. Tradução em português autorizada da edição em inglês da obra Just Hibernate, ISBN 9781449334376 2014 Madhusudhan Konda. Esta tradução é publicada e vendida com a permissão da O'Reilly Media, Inc., a qual detém ou controla todos os direitos para publicação e venda desta obra. Novatec Editora Ltda. [2014]. Todos os direitos reservados e protegidos pela Lei 9.610 de 19/02/1998. É proibida a reprodução desta obra, mesmo parcial, por qualquer processo, sem prévia autorização, por escrito, do autor e da Editora. Editor: Rubens Prates Tradução: Lúcia Ayako Kinoshita Revisão gramatical: Marta Almeida de Sá Editoração eletrônica: Carolina Kuwabata ISBN: 978-85-7522-355-0 Histórico de impressões: Agosto/2014 Primeira edição Novatec Editora Ltda. Rua Luís Antônio dos Santos 110 02460-000 São Paulo, SP Brasil Tel.: +55 11 2959-6529 Email: novatec@novatec.com.br Site: www.novatec.com.br Twitter: twitter.com/novateceditora Facebook: facebook.com/novatec LinkedIn: linkedin.com/in/novatec

capítulo 1 O básico do Hibernate Há dois mundos diferentes de software: um é o mundo Java, em que nada além de objetos são conhecidos, enquanto o outro é o mundo do banco de dados relacional, em que os dados reinam. Os desenvolvedores Java sempre trabalham com objetos representando estados e comportamentos que modelam problemas do mundo real. A persistência de objetos é um requisito fundamental em aplicações Java. O estado é modelado de modo a ser persistente em repositórios duradouros para que ele se torne permanente. Por outro lado, quando for o momento de armazenar os dados, é preciso contar com os bancos de dados relacionais, em que os dados são tradicionalmente representados em um formato linha-coluna, com relacionamentos e associações. Trazer os objetos Java para o mundo relacional é sempre uma tarefa desafiadora e complexa para os desenvolvedores Java. Esse processo normalmente é chamado de ORM (Object-Relational Mapping, ou Mapeamento Objeto-Relacional). Este capítulo define o tom para a nossa discussão sobre o Hibernate, inicialmente apresentando o domínio do problema da persistência de objetos. Iremos explorar as tecnologias e as ferramentas, como o JDBC e o Hibernate, que nos ajudam a encarar esse desafio. Iremos comparar e contrastar ambas as tecnologias e aprenderemos de que modo o Hibernate atinge a persistência no modelo objeto-relacional, com facilidade e conforto. 18

Capítulo 1 O básico do Hibernate 19 Nascimento do Hibernate Suponha que estejamos fazendo o design de um sistema de Internet banking. Esperamos que o banco mantenha uma cópia segura de nossas contas, dos detalhes pessoais, das preferências e das transações. Isso significa que, para serem duradouros, os dados da aplicação devem ser persistentes em um espaço de armazenamento permanente. No contexto dessa aplicação bancária, por dados persistentes quero dizer o cliente, o endereço, a conta e outros objetos do domínio que possam ter sido modelados em nosso design. Os dados que passarem a ser persistentes por meio de nossa aplicação irão sobreviver à própria aplicação por exemplo, podemos mudar de Internet banking para phone banking, porém os dados criados pela nossa aplicação bancária devem continuar visíveis ou disponíveis, caso sejam necessários. Portanto agora sabemos que tornar os objetos persistentes (seus estados correspondem aos dados que devemos ser persistentes) é um requisito fundamental para a maioria das aplicações do mundo real. Para salvar os dados, precisamos de espaços de armazenamento duradouros, que são chamados de bancos de dados. Há uma enorme variedade de fornecedores de bancos de dados (como Oracle, MySQL, DB2, JavaDB e outros), com uma longa lista de diversos detalhes e acessórios. Como podemos tornar a estrutura de um objeto persistente em um banco de dados? As empresas empregam linguagens orientadas a objeto (por exemplo, o Java) como suas plataformas de programação, e bancos de dados relacionais (por exemplo, Oracle, MySQL, Sybase etc.) para o armazenamento de dados. A existência dessas duas tecnologias de software é mandatória para a maioria das aplicações do mundo real, apesar da chamada incompatibilidade de impedância objeto-relacional. Discutiremos essa incompatibilidade em detalhes no próximo capítulo, porém, para efeito de introdução, explicarei seus principais pontos a seguir: A herança é o princípio fundamental da programação orientada a objetos, sem a qual seria impossível fazer o design das associações entre objetos. Os bancos de dados não compreendem a herança!

20 Introdução ao Hibernate Quando se trata do rico conjunto de associações entre objetos, como de um para um (one-to-one), de um para muitos (one-to-many) e de muitos para muitos (many-to-many), os bancos de dados deixam a desejar, pois eles não conseguem suportar todos os tipos de relacionamento. Por fim, há também uma incompatibilidade de identidade: os objetos apresentam tanto identidade quanto igualdade, enquanto os registros do banco de dados são identificados por meio dos valores de suas colunas. Os desenvolvedores atenuam essas diferenças ao empregar vários frameworks desenvolvidos internamente, além de outras soluções técnicas e estratégias. O Java tem um conjunto-padrão de ferramentas para acessar bancos de dados. Esse conjunto é chamado de API (Application Programming Interface, ou Interface de Programação de Aplicativos) JDBC (Java Database Connectivity). A API foi muito bem empregada em aplicações Java até recentemente. Embora ela seja bem adequada para projetos de pequeno porte, a API se torna bem complicada (e, às vezes, fica fora de controle) à medida que a complexidade do modelo do domínio aumenta. A API também inclui muito código boilerplate 1 repetitivo, exigindo que o desenvolvedor faça muita codificação manual. Além do mais, lidar com o mapeamento do modelo objeto-relacional também é uma tarefa árdua! Essa era a questão complicada para os desenvolvedores: todos desejavam ter uma ferramenta simples para tornar os dados persistentes, sem que houvesse muitas dores de cabeça. A equipe do Hibernate identificou as lacunas no espaço de mapeamento ORM e criou um framework simples que facilitaria a vida do desenvolvedor. Foi aí que nasceu o Hibernate! O Hibernate fez sucesso imediato e é, indiscutivelmente, a ferramenta mais popular de código aberto no domínio das ferramentas ORM. O framework foi adotado pela comunidade, da noite para o dia, em virtude de sua simplicidade e dos recursos eficazes. 1 N.T.: Código boilerplate corresponde a códigos que devem ser incluídos em vários lugares com pouca ou nenhuma alteração.

Capítulo 1 O básico do Hibernate 21 Domínio do problema Antes de mergulhar de cabeça na exploração do Hibernate em detalhes, vamos dar uma olhada em um exemplo do tipo de problema para o qual o Hibernate foi criado para resolver. Todos nós (bem, pelo menos a maioria de nós) adoramos filmes. Obviamente, não temos todo o tempo do mundo para assistir a esses filmes quando eles chegam ao cinema. Desse modo, criamos uma lista de desejos com os filmes a que gostaríamos de assistir. Por esse motivo, um belo dia, acordamos e decidimos criar uma aplicação simples chamada JustMovies! É uma aplicação baseada em web que permite aos usuários abrir uma conta e criar sua lista de desejos contendo os filmes. Os usuários podem retornar a qualquer momento ao site a fim de modificar ou apagar os filmes de sua lista de desejos. Como devemos armazenar a lista para cada usuário, é mandatório que essa lista de desejos seja armazenada em um repositório duradouro, por exemplo, em um banco de dados. Vamos, inicialmente, criar uma aplicação Java simples que armazene e obtenha os filmes do banco de dados. A aplicação MovieManager Considere uma aplicação Java chamada MovieManager, cuja tarefa principal seja salvar, encontrar e obter filmes de um banco de dados. Além de codificar a aplicação Java, devemos ter uma tabela no banco de dados para armazenar informações sobre o filme. A tabela MOVIES armazenará os dados dos filmes na forma de linhas, conforme mostrado na tabela 1.1. Tabela 1.1 MOVIES ID TITLE DIRECTOR SYNOPSIS 1 Top Gun Tony Scott When Maverick encounters a pair of MiGs 2 Jaws Steven Spielberg A tale of a white shark! Cada linha representará uma instância de Movie em nossa aplicação VanillaMovieManager.

22 Introdução ao Hibernate Vamos fingir que vivemos em um mundo sem o Hibernate. Criaremos um pouco de código de exemplo usando o JDBC que, esperamos, vá atender aos nossos requisitos. Usando o JDBC O primeiro passo em qualquer aplicação de banco de dados consiste em estabelecer com ele uma conexão. Uma conexão é uma porta de entrada para o banco de dados para executar as operações sobre os dados a partir de uma aplicação Java. O JDBC disponibiliza uma API de conexão para criar conexões de acordo com as propriedades do banco de dados que forem disponibilizadas. Os fornecedores de bancos de dados normalmente implementam uma classe que armazena o sistema de conexão com o banco de dados por exemplo, para o banco de dados MySQL, é a classe com.mysql.jdbc.driver, e para o banco de dados JavaDB (derby), é org.apache.derby.jdbc.embeddeddriver. Observe que usamos o banco de dados MySQL ao longo do livro. Consulte a seção Configurando o Hibernate na página XX para obter detalhes sobre como criar o projeto e o banco de dados. O método getconnection, exibido no trecho de código a seguir, mostra o procedimento para criar uma conexão com o banco de dados: public class VanillaMovieManager { private Connection connection = null; // Propriedades do banco de dados private String url = "jdbc:mysql://localhost:3307/jh"; private String driverclass = "com.mysql.jdbc.driver"; private String username = "mkonda"; private String password = "mypass";... private Connection getconnection() { try { Class.forName(driverClass).newInstance(); connection = DriverManager.getConnection(url, username, password); catch (Exception ex) { System.err.println("Exception:"+ ex.getmessage());

Capítulo 1 O básico do Hibernate 23 return connection; Nesse trecho de código, inicialmente instanciamos a classe driver e, em seguida, obtivemos uma conexão usando DriverManager. Após termos estabelecido a nossa conexão com o banco de dados com sucesso, o próximo passo consiste em criar um método para a persistência e a query de uma entidade Movie. A maior parte dos métodos deverá ser familiar caso você já tenha alguma experiência com código JDBC. Prosseguindo com o desenvolvimento de nossa aplicação, vamos acrescentar alguns métodos que irão salvar os filmes no banco de dados e os acessarão a partir daí. Chamaremos esses métodos de persistmovie e querymovies, respectivamente. A implementação desses métodos está sendo mostrada na listagem de código a seguir: public class VanillaMovieManager { private String insertsql = "INSERT INTO MOVIES VALUES (?,?,?,?)"; private String selectsql = "SELECT * FROM MOVIES";... private void persistmovie() { try { PreparedStatement pst = getconnection().preparestatement(insertsql); pst.setint(1, 1001); pst.setstring(2, "Top Gun"); pst.setstring(3, "Action Film"); pst.setstring(4, "Tony Scott"); // Executa a instrução pst.execute(); System.out.println("Movie persisted successfully!"); catch (SQLException ex) { System.err.println(ex.getMessage()); ex.printstacktrace();

24 Introdução ao Hibernate private void querymovies() { try { Statement st = getconnection().createstatement(); ResultSet rs = st.executequery("select * FROM MOVIES"); while (rs.next()) { System.out.println("Movie Found: " + rs.getint("id") + ", Title:" + rs.getstring("title")); catch (SQLException ex) { System.err.println(ex.getMessage()); Eis o que fizemos no código de exemplo anterior: 1. Criamos uma PreparedStatement a partir da conexão usando a string insertsql. 2. Definimos a instrução com valores (valores de colunas em relação a números de colunas: 1 é o ID, 2 é o título etc.). 3. Executamos a instrução que deve inserir o filme na tabela. 4. Fizemos uma query no banco de dados em busca de todos os filmes (Movies) e os exibimos no console. Os passos são basicamente autoexplicativos. Criamos uma PreparedStatement e a executamos após configurar os valores apropriados nela para cada coluna. Após sabermos que a execução foi bem-sucedida, fizemos uma query no banco de dados usando uma instrução SELECT para acessar todos os filmes disponíveis e exibi-los no console. Entretanto há alguns pontos a serem observados: Utilizamos uma instrução SQL predefinida para inserir (ou selecionar) os valores das colunas.

Capítulo 1 O básico do Hibernate 25 Definimos os valores das colunas, um por um, usando o número da posição (ou o nome da coluna). Capturamos SQLException caso o código não se comporte adequadamente. Em programas simples, essa maneira de criar as instruções com os valores e executá-las é adequada. No entanto os tipos de programa com os quais iremos lidar no mundo real são muito mais complexos. O JDBC funcionará se você estiver disposto e for capaz de criar e administrar um grande volume de código que não esteja diretamente ligado ao seu problema. Além disso, o uso do JDBC pode representar um desafio se você tiver muitas tabelas ou relacionamentos complexos entre os objetos. Não estamos lidando com os dados em qualquer formato usando nossos princípios favoritos de orientação a objetos! Aperfeiçoando a aplicação para filmes Não seria ideal chamar um método como persist() em uma classe utilitária para que o objeto Movie se tornasse imediatamente persistente? Afinal de contas, somos programadores orientados a objetos; desejar esse recurso não é nenhum pecado! Para alcançar esse objetivo, criaremos um POJO (Plain Old Java Object) que representa um filme. Para todo filme de celuloide disponibilizado (ou a ser disponibilizado), teremos um novo objeto Movie criado. O POJO Movie está sendo definido aqui: public class Movie { private int id = 0; private String title = null; private String synopsis = null; private String director = null;... // Setters e getters foram omitidos

26 Introdução ao Hibernate Portanto tudo de que precisamos agora é de um recurso que torne esse objeto POJO persistente em nossa tabela MOVIES do banco de dados essencialmente convertendo o modelo de objeto (o objeto Movie) em um modelo relacional (linha da tabela). Vamos criar uma classe MoviePersistor que possa realizar essa tarefa: // Pseudocódigo public class MoviePersistor { public void persist(movie movie) { // O código para tornar um filme persistente deve ser inserido aqui public void fetch(string title) { // O código para acessar um filme pelo título deve ser inserido aqui... Ainda não implementamos as funcionalidades persist ou fetch; esse não é o ponto principal do programa. Agora vamos ver como é fácil tornar qualquer objeto Movie persistente por meio da classe utilitária MoviePersistor, como demonstrado neste teste de exemplo: // Pseudocódigo MoviePersistor moviepersistor = new MoviePersistor(); Movie movie = new Movie(); movie.setid(1); movie.settitle("jaws"); movie.setdirector("steven Spielberg"); movie.setsynopsis("story of a great white shark!"); moviepersistor.persist(movie); Não é incrível? Um POJO que representa um filme de celuloide torna-se persistente na forma de uma linha de registro em uma tabela do banco de dados modelo de objetos para modelo relacional por meio de uma classe utilitária! Tudo vai bem até agora, exceto pelas implementações propriamente ditas dos métodos persist e fetch. Para implementar essas funcionalidades, precisamos não só do recurso de conexão com um banco de dados, mas

Capítulo 1 O básico do Hibernate 27 também de um mecanismo para converter o objeto em uma linha (por exemplo, mapeando as propriedades de nosso objeto para as colunas do banco de dados). Poderíamos criar nosso próprio framework de classes para ocultar os detalhes dessas conversões e os mecanismos de persistência (que podem usar as boas e velhas instruções JDBC nos bastidores). Embora implementar esse framework não seja uma ciência incrivelmente complicada, seria um trabalho inconveniente e que iria consumir tempo, para começar. Com o passar do tempo, os requisitos de persistência de uma empresa podem ser alterados ou pode até mesmo haver uma migração do banco de dados, por exemplo, de Oracle para MySQL. Isso significa que o framework deverá ser bastante genérico e levar em consideração uma grande variedade de requisitos funcionais e técnicos antes de atingir seu objetivo. Em minha experiência, frameworks desse tipo, desenvolvidos internamente, são impossíveis de administrar, são inflexíveis, não permitem escalação e, às vezes, ficam desatualizados também! A menos que o requisito seja realmente muito específico para uma empresa (sua empresa pode querer efetuar a persistência de dados em Marte!), recomendo fortemente que você pesquise na Internet e escolha um framework que satisfaça as nossas premissas de forma bastante aproximada. Porém, antes de começar a criar esse código, deixe-me ser o portador de boas notícias (caso você ainda não tenha ouvido falar disto): já existe um ótimo framework que faz exatamente isso persistência de objetos em um banco de dados relacional, e ele se chama Hibernate! Agora que temos um framework para persistência, vamos ver como o mesmo método que faz nosso filme ser persistente pode ser refatorado por meio do Hibernate: public class BasicMovieManager { private void persistmovie(movie movie) { Session session = sessionfactory.getcurrentsession();... session.save(movie);...

28 Introdução ao Hibernate Você percebeu que salvamos a instância de Movie em um banco de dados ao executar uma única linha de código: session.save(movie)? Não é isso que queríamos anteriormente uma classe que simplesmente salvaria objetos persistentes de maneira orientada a objetos? As classes da API do Hibernate expõem diversos métodos para manipular objetos Java com facilidade e conforto. Não precisamos criar trechos de código usando o JDBC nem arregaçar as mangas e implementar um framework enquanto coçamos nossas cabeças e consumimos litros de cafeína! O Hibernate oferece o recurso de persistência de objetos; entretanto há uma configuração e um mapeamento que devem ser feitos uma só vez para que o Hibernate possa saber quais são as nossas intenções. Exploraremos esses detalhes de forma bem geral nas próximas seções. Usando o Hibernate Os passos-padrões a serem seguidos para criar uma aplicação Hibernate são: 1. Configurar a conexão com o banco de dados. 2. Criar as definições de mapeamento. 3. Efetuar a persistência das classes. Aqui estão os passos comuns envolvidos no desenvolvimento da versão Java-Hibernate de nossa aplicação MovieManager: 1. Crie um objeto Movie do domínio (POJOs do modelo de domínio, que representam tabelas de dados). 2. Crie arquivos de configuração, por exemplo, os arquivos com as propriedades do Hibernate e os de mapeamento. 3. Crie um cliente de teste que administre (insira/atualize/apague/ acesse) os filmes (Movies). Já preparamos um POJO Movie, como mostrado em trechos anteriores de código, portanto não é preciso repetir essa parte novamente.

Capítulo 1 O básico do Hibernate 29 O coração de qualquer aplicação Hibernate está em sua configuração. Existem duas partes da configuração, necessárias a qualquer aplicação Hibernate: uma para criar as conexões com o banco de dados e outra para criar o mapeamento objeto-tabela. Como ocorre no JDBC, devemos fornecer informações do banco de dados para a nossa aplicação para que ela possa estabelecer uma conexão e manipular os dados. A configuração de mapeamento define quais propriedades dos objetos serão mapeadas para quais colunas da tabela. Não entraremos em detalhes aqui, pois o objetivo deste capítulo é apresentar uma introdução rápida a você! Vamos dar uma olhada nos passos-padrões para criar uma aplicação Hibernate nas seções a seguir. Configurando a conexão com o banco de dados Para criar uma conexão com o banco de dados, o Hibernate deve conhecer os detalhes de nosso banco de dados, as tabelas, as classes e outros mecanismos. Essas informações, de modo ideal, são disponibilizadas na forma de um arquivo XML (normalmente chamado de hibernate.cfg.xml) ou como um arquivo texto simples, contendo pares de nome/valor (normalmente chamado de hibernate.properties). Neste exercício, usaremos o estilo XML. Chamamos esse arquivo de hibernate.cfg.xml para que o framework possa carregá-lo automaticamente. O trecho de código a seguir descreve um arquivo de configuração desse tipo. Como estou usando o MySQL como banco de dados, os detalhes da conexão com o banco de dados MySQL são declarados neste arquivo hibernate.cfg.xml: <hibernate-configuration> <session-factory> <property name="connection.url"> jdbc:mysql://localhost:3307/jh </property> <property name="connection.driver_class"> com.mysql.jdbc.driver </property>

30 Introdução ao Hibernate <property name="connection.username"> mkonda </property> <property name="connection.password"> password </property> <property name="dialect"> org.hibernate.dialect.mysql5dialect </property> <mapping resource="movie.hbm.xml" /> </session-factory> </hibernate-configuration> Esse arquivo contém informações suficientes para estabelecer uma conexão ativa com um banco de dados MySQL. As propriedades anteriores também podem ser expressas na forma de pares nome/valor. Por exemplo, aqui estão as mesmas informações representadas como pares nome/valor em um arquivo texto chamado hibernate.properties: hibernate.connection.driver_class = com.mysql.jdbc.driver hibernate.connection.url = jdbc:mysql://localhost:3307/jh hibernate.dialect = org.hibernate.dialect.mysql5dialect connection.url indica o URL com o qual devemos nos conectar, driver_class representa a classe Driver relevante para estabelecer uma conexão e dialect indica o dialeto de banco de dados que estamos usando (MySQL, nesse caso). Se você estiver seguindo a abordagem do arquivo hibernate.properties, observe que todas as propriedades são prefixadas com hibernate e seguem um padrão hibernate.* properties, por exemplo. Além de fornecer as propriedades de configuração, também é preciso disponibilizar os arquivos de mapeamento e suas localizações. Como mencionado anteriormente, um arquivo de mapeamento contém o mapeamento entre propriedades de objetos e os valores das colunas. Esse mapeamento é feito em um arquivo separado, normalmente com sufixo igual a.hbm.xml.

Capítulo 1 O básico do Hibernate 31 Devemos fazer com que o Hibernate conheça nossos arquivos de definição de mapeamentos ao incluir um elemento com a propriedade mapping no arquivo de configuração anterior, como mostrado aqui: <hibernate-configuration> <session-factory>... <mapping resource="movie.hbm.xml" /> <mapping resource="account.hbm.xml" /> <mapping resource="trade.hbm.xml" /> </session-factory> </hibernate-configuration> O atributo resource indica o nome do recurso de mapeamento que o Hibernate deve carregar. Nesse caso, Movie.hbm.xml é o arquivo de mapeamento e contém detalhes de como um objeto Movie é mapeado para uma tabela MOVIE. Você pode ver também outros arquivos de mapeamento, como Account.hbm.xml e Trade.hbm.xml. Daremos uma olhada nesses arquivos em breve. O que o Hibernate faz com esse arquivo de propriedades? O framework Hibernate carrega esse arquivo para criar uma SessionFactory, que é uma classe global threadsafe (segura para thread) de factory, a fim de criar Sessions. O ideal seria criar uma única SessionFactory e compartilhá- -la por toda a aplicação. Observe que uma SessionFactory é definida para um, e somente um, banco de dados. Por exemplo, se houver outro banco de dados, além do MySQL, você deverá definir a configuração relevante em hibernate.hbm.xml a fim de criar uma SessionFactory separada para esse banco de dados também. O objetivo de SessionFactory é criar objetos Session. Session é um gateway para o nosso banco de dados. Cuidar de todas as operações do banco de dados, como salvar, carregar e obter registros das tabelas relevantes, é tarefa de Session. O framework também mantém uma mídia de transações em torno de nossa aplicação. As operações envolvendo acesso ao banco de dados são encapsuladas em uma única unidade de trabalho chamada transação. Portanto todas as operações nessa transação devem ser bem- -sucedidas ou deverá ocorrer um rollback (reversão).

32 Introdução ao Hibernate Tenha em mente que a configuração é usada para criar uma Session por meio de uma instância de SessionFactory. Antes de prosseguir, observe que os objetos Session não são thread-safe e, desse modo, não devem ser compartilhados por classes diferentes. Veremos os detalhes sobre como esses objetos devem ser usados à medida que avançarmos neste livro. Criando definições de mapeamento Depois que tivermos a configuração de conexão pronta, o próximo passo será preparar o arquivo Movie.hbm.xml, constituído de definições de mapeamento objeto-tabela. O trecho de código XML a seguir define o mapeamento de nosso objeto Movie para a tabela MOVIES: <hibernate-mapping> <class name="com.madhusudhan.jh.domain.movie" table="movies"> <id name="id" column="id"> <generator class="native"/> </id> <property name="title" column="title"/> <property name="director" column="director"/> <property name="synopsis" column="synopsis"/> </class> </hibernate-mapping> Há muita coisa acontecendo nesse arquivo de mapeamento. O elemento hibernate-mapping armazena todas as definições de mapeamento de classe para tabela. Mapeamentos individuais por objeto são declarados dentro do elemento class. O atributo name da tag class refere-se à classe com.madhusudhan.jh.domain.movie de nosso domínio POJO, enquanto o atributo table refere-se à tabela MOVIES na qual os objetos se tornarão persistentes. As propriedades restantes representam o mapeamento das variáveis do objeto para as colunas da tabela (por exemplo, id é mapeado para ID, title para TITLE, director para DIRECTOR etc.). Cada objeto deve ter um identificador único semelhante a uma chave primária da tabela. Definimos esse identificador ao implementar a tag id usando uma estratégia do tipo native (nativa). Não preste muita atenção a esse id e à estratégia de sua geração por enquanto. Discutiremos esses aspectos em detalhes nos próximos capítulos.

Capítulo 1 O básico do Hibernate 33 Persistência dos objetos Agora que a configuração está fora de nosso caminho, vamos criar um cliente que torne os objetos persistentes com a ajuda do Hibernate. Precisamos da instância de SessionFactory a partir da qual criaremos um objeto Session. O trecho de código a seguir mostra a configuração inicial para a criação da classe SessionFactory: public class BasicMovieManager { private SessionFactory sessionfactory = null; // Criando SessionFactory usando a versão 4.2 do Hibernate private void initsessionfactory(){ Configuration config = new Configuration().configure(); // Cria um Registry com as propriedades de nossa configuração ServiceRegistry serviceregistry = new ServiceRegistryBuilder().applySettings( config.getproperties()).buildserviceregistry(); // Cria a factory de sessões sessionfactory = config.buildsessionfactory(serviceregistry);... Observe que não temos de mencionar explicitamente os arquivos de mapeamento ou de configuração ou de propriedades, pois o runtime do Hibernate procura nomes de arquivo default como hibernate.cfg.xml ou hibernate.properties no classpath e os carrega. Se tiver um nome que não seja igual ao default, não se esqueça de passá-lo como argumento como em configure("my-hibcfg.xml"), por exemplo. As configurações anteriores para a inicialização da classe SessionFactory são adequadas à versão mais recente do Hibernate na época desta publicação, que era a versão 4.2. A versão 4.x do Hibernate introduziu os registros de serviço, que veremos nos capítulos seguintes.

34 Introdução ao Hibernate Em versões 3.x, o método configure verifica o classpath à procura de um arquivo chamado hibernate.cfg.xml (ou hibernate.properties) para criar um objeto Configuration. Esse objeto de configuração então é usado para criar uma instância de SessionFactory. Se uma verão de Hibernate anterior a 4.x estiver sendo usada, utilize o código a seguir para inicializar SessionFactory: // Criando SessionFactory usando a versão 3.x do Hibernate private void init3x() { sessionfactory = new Configuration().configure().buildSessionFactory(); Em versões 4.x, isso foi levemente alterado pela introdução de ServiceRegistry, que recebe um Map contendo as propriedades, preenchido a partir de um objeto Configuration, como acabou de ser mostrado. Independentemente da versão que você escolher, a SessionFactory criada será a mesma, assim como as Sessions. Criando o método para persistência Agora vamos ver o verdadeiro funcionamento da classe BasicMovieManager. O método para persistência é definido na classe para tornar um filme persistente por meio do método save de Session. Isso está sendo mostrado no trecho de código a seguir: public class BasicMovieManager { private void persistmovie(movie movie) { Session session = sessionfactory.getcurrentsession(); session.begintransaction(); session.save(movie); session.gettransaction().commit(); Parece simples, não é mesmo? Não escrevemos nenhum código desnecessário ou repetitivo e focamos na função principal, que é salvar o objeto.

Capítulo 1 O básico do Hibernate 35 No trecho de código anterior, inicialmente obtivemos uma Session da factory. Em seguida, criamos um objeto de transação (conheceremos melhor as transações nos capítulos seguintes) e tornamos o objeto de entrada Movie persistente usando o método session.save. Por fim, efetuamos o commit da transação e Movie é armazenado permanentemente em nosso banco de dados. Testando os dados persistentes Temos duas maneiras de testar os dados persistentes: executar uma query SQL nativa no banco de dados ou criar um cliente para teste. Podemos executar a query SQL no banco de dados usando algo como SELECT * FROM MOVIES, que acessa todos os registros armazenados por nossa aplicação. A query SELECT do SQL exibe a saída mostrada na tabela 1.2. Tabela 1.2 MOVIES ID TITLE DIRECTOR SYNOPSIS 1 Top Gun Tony Scott Maverick is a hot pilot 2 Jaws Steven Spielberg A tale of a white shark! De modo alternativo, podemos criar outro método em nosso cliente de teste, por exemplo, findmovie. Esse método usará o método load de Session para acessar o registro do banco de dados. Chamamos o método findmovie passando o ID do filme como argumento, a fim de acessar o filme: public class BasicMovieManager {... private void findmovie(int movieid) { Session session = sessionfactory.getcurrentsession(); session.begintransaction(); Movie movie = (Movie)session.load(Movie.class, movieid); System.out.println("Movie:"+movie); session.gettransaction().commit();

36 Introdução ao Hibernate O método load da API de Session acessa o objeto Movie apropriado para um dado identificador. Se estiver pensando que o Hibernate pode estar usando uma instrução SELECT nos bastidores, então você está certo! Caso queira acessar todos os filmes da tabela, crie um objeto Query com a string de query simples "from Movie" e execute-a. O método list da query (criada por meio de session.createquery) retorna uma lista de filmes na forma de uma List, como mostrado a seguir: public class BasicMovieManager { // Acessando todos os filmes private void findall() { Session session = sessionfactory.getcurrentsession(); session.begintransaction(); List<Movie> movies = session.createquery("from Movie").list();* session.gettransaction().commit(); System.out.println("All Movies:"+movies);... Configurando o Hibernate Criar um projeto Hibernate é fácil. O projeto que preparei para este livro é um código baseado em Maven, desenvolvido no IDE NetBeans. Não entrarei em detalhes sobre como configurar o ambiente, porém os passos a seguir deverão ajudar você. Embora eu tenha usado o NetBeans para desenvolver o código, você poderá usar qualquer um de seus IDEs favoritos para trabalhar neste projeto. Além do mais, você pode trocar o MySQL por qualquer outro banco de dados, incluindo aqueles em memória como o Derby ou o HyperSQL. Inicialmente, configure o ambiente essencial de desenvolvimento, constituído do JDK 5.0+, do IDE NetBeans, do Maven e do banco de dados MySQL (pode ser que você já tenha esse ambiente!). Eu usei o JDK 6, o NetBeans 7.3, o Maven 3.2 e o MySQL 5.2 para desenvolver o código, e a versão do Hibernate é a 4.2.3.Final.

Capítulo 1 O básico do Hibernate 37 Depois que tiver organizado o seu ambiente de desenvolvimento, o próximo passo é criar um projeto Maven no NetBeans (ou no Eclipse). Adicione as dependências apropriadas do Hibernate no arquivo pom.xml, como mostrado aqui: <project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelversion>4.0.0</modelversion> <groupid>com.madhusudhan</groupid> <artifactid>just-hibernate</artifactid> <version>0.0.1-snapshot</version> <dependencies> <dependency> <groupid>org.hibernate</groupid> <artifactid>hibernate-core</artifactid> <version>4.2.3.final</version> </dependency> <dependency> <groupid>mysql</groupid> <artifactid>mysql-connector-java</artifactid> <version>5.1.18</version> </dependency>... </project> O Maven resolverá as dependências relacionadas ao criar o projeto. Recomendo fazer o download do código-fonte do livro e importar o projeto em seu IDE favorito. O próximo passo é configurar o seu banco de dados. Se você já tiver um banco de dados, esse passo poderá ser ignorado. Estou usando o banco de dados MySQL. Faça o download do pacote MySQL mais recente e instale-o em seu computador (pode ser que seja necessário consultar o manual para configurá-lo corretamente). Você pode experimentar executar os exemplos deste livro usando qualquer outro banco de dados.

38 Introdução ao Hibernate Depois que tiver o MySQL (ou qualquer outro banco de dados) instalado, não se esqueça de criar um esquema chamado JH, como mostrado aqui: CREATE SCHEMA JH; A maioria das tabelas desse projeto foi gerada automaticamente pelo Hibernate, ou seja, o Hibernate cria as tabelas (caso elas não existam) durante o processo de leitura de sua configuração. É preciso definir uma propriedade, hbm2ddl.auto, no arquivo de configuração do Hibernate (hibernate.cfg.xml) com o valor adequado para que essa geração automática ocorra, da seguinte maneira: <property name="hbm2ddl.auto">update</property> Quando essa propriedade é definida, as tabelas são criadas automaticamente caso não existam, ou são atualizadas se houver uma mudança no esquema da tabela. Nunca use a propriedade hbm2ddl.auto em ambiente de produção! Você deve criar um esquema com todas as definições de tabela e implantá-lo em ambiente de produção por meio de um processo adequado de disponibilização de versão. Basicamente, é isso! Queríamos ter um mecanismo que ocultasse os detalhes de instruções JDBC complicadas e das conexões. Sonhamos em criar métodos utilitários que armazenassem um objeto POJO diretamente no banco de dados, sem o trabalho de escrever/ler as colunas. Realizamos nossos sonhos e desejos ao adotar o Hibernate! Você pode ter muitas perguntas a fazer, porém elas serão esclarecidas à medida que prosseguirmos em nossa jornada, portanto fique ligado!

Capítulo 1 O básico do Hibernate 39 Resumo Neste capítulo, conhecemos o domínio do problema do modelo objeto- -relacional ao acompanharmos um exemplo. Embora possamos usar o JDBC para acessar dados, descobrimos que isso exige muitos mapeamentos manuais e código repetitivo desnecessário. Demos um pequeno passo e introduzimos o Hibernate para resolver o problema da persistência de dados de objetos para dados relacionais. De um ponto de vista geral, demos uma olhada nos conceitos de SessionFactory e de Sessions do Hibernate. Refatoramos o exemplo do JDBC de modo a usar o framework Hibernate e tornamos os dados persistentes com sucesso, efetuando queries de POJOs, conforme esperado. No próximo capítulo, discutiremos os fundamentos do Hibernate em detalhes.