1 / 52

Hibernate

Hibernate. Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kely {gkmo@cin.ufpe.br}. O que é?. Hibernate é uma moderna solução de mapeamento objeto-relacional(ORM) Persistência transparente (POJO/Java Beans) “Lazy Fetching” Uso de uma Cache

terri
Download Presentation

Hibernate

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kely {gkmo@cin.ufpe.br}

  2. O que é? • Hibernate é uma moderna solução de mapeamento objeto-relacional(ORM) • Persistência transparente (POJO/Java Beans) • “Lazy Fetching” • Uso de uma Cache • Três estratégias para o mapeamento de heranças

  3. O que é?

  4. Pra que transparência? • Persistência sem impacto no código dos objetos de negócio • Qualquer classe pode ser uma classe persistente sem ser necessário implementar nenhuma classe ou interface • Classes persistentes podem ser usadas fora do contexto de persistência (ex Testes) • Total portabilidade sem dependências

  5. Problemas dos BDRs • Modelagem • Não há polimorfismo • Não há herança • Lógica de negócio • Stored procedures -> perca de portabilidade

  6. Vantagens dos RDBs • Trabalhar com grandes quantidades de dados • Busca, ordenação • Trabalhar com conjuntos de dados • Junções e agregações • Compartilhamento • Concorrência (Transações) • Muitas aplicações • Integridade • Restrições (Constraints) • Isolação de transações

  7. Obviamente, ainda precisamos dos RDBs

  8. Objetivo • Aproveitar-se das vantagens oferecidas pelos RDBs • Isso sem perder a orientação a objetos

  9. Objetivo Real • Ter menos trabalho  • Ter um DBA feliz 

  10. Em prática • Locadora em partes...

  11. Em prática • Classe Persistente • Construtor default • Pares de Get´s e Set´s • Uma propriedade identificadora package br.org.citi.pec.locadora; public class Filme { private int codigo; private String nome; public int getCodigo() { return codigo; } private void setCodigo(int codigo) { this.codigo = codigo; } public String getNome() { return nome; } private void setNome(int nome) { this.nome = nome; } }

  12. Em prática • Mapeamento XML • Metadado legível • Mapeamento de tabelas e colunas <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <classname="br.org.citi.pec.locadora.Filme" table="filmes"> <idname="codigo" column="filme_id"> <generatorclass="native" /> </id> <propertyname="nome" column="nome"/> </class> </hibernate-mapping>

  13. Em prática • Salvando um objeto Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Filme filme = new Filme(); filme.setNome(novoNome); session.save(filme); tx.commit(); session.close(); Também pode ser usado saveOrUpdate

  14. Em prática • Carregando um objeto Session session = sessionFactory.openSession(); Filme filme = (Filme) session.load(Filme.class, new Integer(filmeId); session.close(); • Não use load para determinar se um objeto existe (uma exceção é lançada neste caso) • Use get. Este retorna null caso o objeto não exista

  15. Em prática • Removendo um objeto Session session = sessionFactory.openSession(); Transaction tx = s.beginTransaction(); Filme filme = (Filme) session.get(Filme.class, new Integer(filmeId); session.delete(filme); tx.commit(); session.close();

  16. Em prática • Atualizando um objeto (Dirty Checking) • Obetendo um filme e alterando seu nome Session session = sessionFactory.openSession(); Transaction tx = s.beginTransaction(); Filme filme = (Filme) session.get(Filme.class, new Integer(filmeId); filme.setNome(novoNome); tx.commit(); session.close(); Não é necessário uma chamada explicita do update

  17. Estado dos Objetos • Alguns conceitos sobre objetos • Transiente. • Nunca persistido. Não associado a nenhuma sessão (Session) • Persistente • Associado a uma única sessão • Desacoplado (Detached) • Já persistido, mas não associado a nenhuma sessão

  18. Estado dos Objetos • Dirty Checking só funciona em objetos persistentes • Use update para objetos desacoplados

  19. Mais prática • Melhorando nosso modelo...

  20. Mais prática • Classes persistentes package br.org.citi.pec.locadora; public class Cliente { private String login; private String CPF; private String nome; privateSet locacoes = new Hashset(); //... Get´s e Set´s }

  21. Mais prática • Classes persistentes package br.org.citi.pec.locadora; public class Locacao { private int id; private Filme filme; private Cliente cliente; private Date dataLocacao; private Date datadevolucao; //... Get´s e Set´s }

  22. Mais prática • XML... <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <classname="br.org.citi.pec.locadora.Cliente" table="Clientes"> <idname="login"/> <propertyname="nome" /> <propertyname="cpf" /> <setname="locacoes"> <keycolumn="cliente_login" /> <one-to-manyclass="br.org.citi.pec.locadora.Locacao"/> </set> </class> </hibernate-mapping>

  23. Mais prática • XML... <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <classname="br.org.citi.pec.locadora.Locacao" table="Locacoes"> <idname="id"> <generatorclass="native" /> </id> <propertyname="dataLocacao" /> <propertyname="dataDevolucao" /> <many-to-one name="cliente" class="br.org.citi.pec.locadora.Cliente" column="cliente_login"/> <many-to-one name="filme" class="br.org.citi.pec.locadora.Filme" column="filme_id"/> </class> </hibernate-mapping>

  24. Mais prática • Persistência transitiva Locacao locacao = new Locacao(); Locacao.setDataLocacao(new Date()); Session session = sessionFactory.openSession(); Transaction tx = s.beginTransaction(); Filme filme = (Filme) session.get(Filme.class, new Integer(filmeId); Cliente cliente = (Cliente) session.get(Cliente.class, login); locacao.setCliente(cliente); locacao.setFilme(filme); cliente.getLocacoes().add(locacao); tx.commit(); session.close();

  25. Herança • Estratégias para o mapeamento de herança • Uma tabela por hierarquia de classes • Uma tabela por subclasse • Uma tabela por classe concreta

  26. Herança • Uma tabela por subclasse <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <classname="br.org.citi.pec.locadora.Cliente" table="Clientes"> <idname="login" column="LOGIN" /> ... <joined-subclass name="br.org.citi.pec.locadora.ClienteEspecial" table="ClientesEspeciais"> <key column="LOGIN" /> <property ... /> ... </joined-subclass> </class> </hibernate-mapping>

  27. Otimizando • Como as coleções são carregadas • Lazy fetching (Default) • Eager (Outer Join) fetching • Indicado nos XML, ou na própria consulta

  28. Lazy fetching • SQL escondido: Cliente cliente = (Cliente) session.get(Cliente.class, login); SELECT … FROM CLIENTES C WHERE C.LOGIN = ? Iterator cliente = cliente.getLocacoes().iterate(); SELECT … FROM LOCACOES L WHERE L.LOGIN_CLIENTE = ? Filme filme = locacao.getFilme(); SELECT … FROM FILMES F WHERE F.FILME_ID = ?

  29. Outer join fetching • SQL escondido: Cliente cliente = (Cliente) session.get(Cliente.class, login); SELECT … FROM CLIENTES C LEFT OUTER JOIN LOCACOES L ON L.LOGIN_CLIENTE = C.LOGIN LEFT OUTER JOIN FILME F ON L.FILME_ID = F.FILME_ID WHERE C.LOGIN = ?

  30. Otimizando • Como otimizar? • Minimizando a leitura de linhas das tabelas • Minimizando a quantidade de comandos SQLs enviados

  31. Otimizando • Minimizando a leitura de linhas das tabelas • Usar lazy fecthing • Minimizando a quantidade de comandos SQLs enviados • Usar outer join fetching

  32. Otimizando • Problemas • Usar lazy fecthing • Problema dos n+1 selects (muitos selects!) • Usar outer join fetching • Problema do produto cartesiano (grandes conjuntos de dados)

  33. Otimizando • Solucionando problemas de otimização • Stratégia de Fecthing definida em tempo de execução • Batch Fecthing • Utilizar um cache de segundo nível

  34. Consultas • HIbernate Query Lanuage • Permite que se expresse quase tudo o que se precisa expressar em SQL, porém mais orientado a objetos • Três maneiras de se fazer consultas no Hibernate • HQL • Criteria • SQL nativo

  35. HQL • Tornar SQL orientado a objetos • Classes e propriedades ao invés de Tabelas e colunas • Polimorfismo • Associações • Total suporte a operações relacionais • Joins • Projeções • Funções agregadas e agrupamento • Ordenação • SubQueries • Chamadas a funções SQL

  36. HQL • A consulta mais simples possivel HQL from Filme • Devolva todos os filmes List filmes = session.createQuery(“from Filme”).list(); • As consultas podem ser paginadas Query query = session.createQuery(“from Filme”); query.setFirstResult(20);query.setMaxResults(30); List filmes = query.list();

  37. HQL • Uma consulta com ordenação from Locacao l order by l.dataLocacao desc • Caso esteja interessado em um único resultado Query query = session.createQuery( “from Locacao l order by l.dataLocacao desc”); Locacao locacao = query.uniqueResult();

  38. HQL • Uma consulta com joins select c from Cliente c left join [fetch] c.locacaoes l where l.dataLocacao > 3/5/2005 • Todos os clientes com suas locações efetuadas após o dia 3 • Definição da estratégia de fetching • Com o fetch: Coleções já inicializadas • Sem o fetch: lazy collections

  39. HQL • HQL suporta os mesmos operadores que SQL • Operadores do HQL: • Comparação: =, <>, <, >, >=, <=, between, not between, in, not in • Nulidade: is null, is not null • Aritméticos: +, -, /, *, %, parênteses • O operador like funciona da mesma forma que SQL • Pode usar funções SQL se o banco suportar

  40. HQL • Projeções + funções agregadas (Report Queries) select c.nome, count(l) from Cliente c, c.locacoes l where l.dataLocacao between(:inicio, :fim) group by c.nome order by count(l)

  41. HQL • Os dados da consulta anterior serão retornados em List de Object[] • Consulta comum para a realização de relatórios • Podemos tornar o processo mais elegante • List list = session.createQuery( • “select new ClienteReportRow(c.nome, count(l)) ” + • “from Cliente c, c.locacoes l ” + • “where l.dataLocacao between(:inicio, :fim) ” + • “group by c.nome ” + • “order by count(l)”). • setDate(“inicion”, inicio). • setDate(“fim”, fim).list();

  42. HQL • Dessa forma evitas-se o uso de vetores de objetos • É necessário que exista uma classe e um construtor previamente definido

  43. HQL • Consultas não precisam aparecer no código • Na verdade, muitas vezes é melhor que não apareçam • Podem ficar nos metadados e serem chamadas pelo nome • Usa-se o método getNamedQuery() • Mas antes, ela precisa ser declarada em algum arquivo de mapeamento List clientes = session.getNamedQuery(“findClienteByName”) .setString(“nome”, nome),list() <query name=“findClienteByName”><![CDATA[ from Cliente c where c.nome like :nome]] </query>

  44. Modelagem OO • “Mais classes que tabelas” • Classse Endereco • Propriedade: rua, numero, bairro... • Rua, numero, bairro,... Colunas da tabela cliente <classname="br.org.citi.pec.locadora.Cliente" table="Clientes"> … <componentname=“endereco” class=“br.org.citi.pec.locadora.Endereco”> <property name=“rua” column=“rua”/> <property name=“numero” column=“numero”/> … </component> </class>

  45. O que mais? • Hibernate também dá suporte a tipos de dados definidos pelo usuário • Interceptadores e EventListeners • Filtros • Definições explicitas dos SQLs de insert e update e load (hibernate 3) ...e mais um pouco!

  46. Sobre configuração • Como obter um SessionFactory? • Programaticamente • Por arquivo XML

  47. Configuração programática Configuration cfg = new Configuration() .setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect"). .setProperty("hibernate.connection.driver_class", "org.hsqldb.jdbcDriver") .setProperty("hibernate.connection.url", "jdbc:hsqldb:file:hsqldb/data") .setProperty("hibernate.connection.username", "sa") .setProperty("hibernate.connection.password", "") .addClass(Filme.class) .addClass(Cliente.class) .addClass(Locacao.class); SessionFactory sessionFactory = cfg.buildSessionFactory();

  48. Configuração XML hibernate.cfg.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <propertyname="hibernate.dialect"> org.hibernate.dialect.MySQLDialect</property> <propertyname="hibernate.connection.driver_class"> org.gjt.mm.mysql.Driver</property> <propertyname="hibernate.connection.username">root</property> <propertyname="hibernate.connection.password">ftBBvEdiC</property> <propertyname="hibernate.connection.url"> jdbc:mysql://localhost/lockar</property> <mappingclass="br.org.citi.pec.locadora.Filme"/> <mappingclass="br.org.citi.pec.locadora.Locacao"/> <mappingclass="br.org.citi.pec.locadora.Cliente"/> </session-factory> </hibernate-configuration> Configuration cfg = new Configuration().configure(); SessionFactory sessionFactory = cfg.buildSessionFactory();

  49. Extras • Hbm2ddl (tool) • Gera o schema do BD a partir das XML de mapeamentos • Usado por linha de comando ou pelo ant <target name="schemaexport"> <taskdef name="schemaexport" classname="org.hibernate.tool.hbm2ddl.SchemaExportTask"classpathref="project.lib.classpath" /> <schemaexport properties="hibernate.properties" quiet="yes" text="yes" drop="no" delimiter=";"output="${basedir}/sql/schema-export.sql"> <fileset dir="src"> <include name="**/*.hbm.xml" /> </fileset> </schemaexport> </target>

  50. Exercícios • Ampliar nosso modelo

More Related