Ferramentas e Tecnologias II Pós-graduação em Banco de Dados para Mercados Corporativos Programação de Sistemas e Bancos de Dados Ferramentas e Tecnologias II Daniel Henriques Moreira dhenriques@gmail.com Daniel Henriques Moreira dhenriques@gmail.com Belém, novembro de 2012
Demoiselle (1/5) Sítio Definição http://www.frameworkdemoiselle.gov.br/ Definição Framework de integração de várias tecnologias e padrões de desenvolvimento na plataforma Java. Baseado em código aberto.
Demoiselle (2/5) Histórico Desenvolvido pelo Serpro desde 2008, com o objetivo de, dentro da empresa: Padronizar as soluções desenvolvidas em Java Uso de arquitetura em camadas; Sugestão de bibliotecas de código aberto (com indicação de versão) para resolver determinados tipos de problemas. Desenvolvimento ainda coordenado pelo Serpro, mas aberto à participação de desenvolvedores independentes; Versão atual: 2.3.0.
Características (úteis ao módulo) (1/2) Demoiselle (3/5) Características (úteis ao módulo) (1/2) Desenvolvimento de aplicações independentes de interface Aplicações web podem utilizar JSF 2; Desenvolvimento de aplicações independentes de banco de dados Uso de JPA 2.
Demoiselle (4/5) Características (úteis ao módulo) (2/2) Utilização de padrões de arquitetura em camadas Camada de persistência Objetos de acesso aos dados (data access objects - DAO). Camada de negócios Controladores de negócio (business controllers - BC). Camada de visão Objetos visuais (visual objects - VO); Managed Beans (MB) Classes de objetos que integram código Java às páginas HTML. Páginas HTML. Domínio de entidades Classes do modelo de dados do problema.
Demoiselle (5/5) Instalação Catálogo de arquétipos de projetos Maven, aplicado no Eclipse http://demoiselle.sourceforge.net/repository/archetype-catalog.xml
JPA 2 (1/43) Sítio (JSR 317) Definição Histórico http://jcp.org/en/jsr/detail?id=317 Definição API capaz de tomar dados orientados a objetos escritos em Java, e persisti-los em tabelas do modelo relacional. Histórico JSR 220, em maio de 2006, definiu o JPA 1.0; Versão atual: 2.0.
JPA 2 (2/43) Providers Instalação? Implementações da JSR 317; Exemplos OpenJPA - http://openjpa.apache.org/; EclipseLink - http://www.eclipse.org/eclipselink/; Hibernate - http://www.hibernate.org/ Utilizado no módulo. Instalação? Neste módulo, incluída nos projetos em fase de desenvolvimento, por meio de arquétipo Maven.
Entidades (Entities) (1/2) JPA 2 (3/43) Entidades (Entities) (1/2) Classes do modelo de dados do problema que devem ser persistidas; Geridas pelo provider utilizado, quanto à sua persistência;
JPA 2 (4/43) Entidades (Entities) (2/2) Ciclo de vida das entidades
Mapeamento objeto-relacional (1/31) JPA 2 (5/43) Mapeamento objeto-relacional (1/31) Entidades são anotadas, de modo a configurar o mapeamento; Anotando Entidades @Entity(name=“<nome-da-tabela>") Marca uma classe do modelo de dados como uma entidade; Define o nome da tabela, no BD, que persistirá objetos desta classe (item name). Aplicação Antes da declaração da classe.
Mapeamento objeto-relacional (2/31) JPA 2 (6/43) Mapeamento objeto-relacional (2/31) Anotando Identidade (1/2) @Id Determina qual atributo da classe servirá como chave primária em sua tabela de persistência; Aplicação Antes do atributo que servirá de chave-primária.
Mapeamento objeto-relacional (3/31) JPA 2 (7/43) Mapeamento objeto-relacional (3/31) Anotando Identidade (2/2) Co-anotação @GeneratedValue Indica que o id será gerado automaticamente pelo sistema; Utilizado para ids que não fazem parte do modelo de dados do problema; Aplicação Antes do atributo que servirá de chave-primária.
Mapeamento objeto-relacional (4/31) JPA 2 (8/43) Mapeamento objeto-relacional (4/31) Anotando Atributos Simples (1/2) @Column Indica em qual coluna da tabela de persistência o atributo será armazenado. Utilizado para atributos de tipo “básico” String, Date, Integer, Long, Byte, Float, etc. Aplicação Antes do atributo a ser persistido.
JPA 2 (9/43) Mapeamento objeto-relacional (5/31) Anotando Atributos Simples (2/2) @Column Formato @Column( name="<nome-da-coluna>", unique=<[true | false]>, nullable=<[true | false]>, insertable=<[true | false]>, updatable=<[true | false]>, length=<+d>, precision=<+d> scale=<+d> )
Mapeamento objeto-relacional (6/31) JPA 2 (10/43) Mapeamento objeto-relacional (6/31) Ignorando Atributos @Transient Indica que um determinado atributo não será persistido na tabela da classe; Aplicação Antes do atributo ignorado.
Mapeamento objeto-relacional (7/31) JPA 2 (11/43) Mapeamento objeto-relacional (7/31) Anotando Herança (1/8) Estratégias Single table; Joined Subclasses; Mapped Superclasses.
Mapeamento objeto-relacional (8/31) JPA 2 (12/43) Mapeamento objeto-relacional (8/31) Anotando Herança (2/8) Estratégia Single Table (1/3) @Inheritance( strategy=InheritanceType.SINGLE_TABLE) Aplicação Antes da definição da superclasse mais genérica. Uma única tabela contém todos os atributos de todas as subclasses e superclasses; Uma coluna a mais, discriminatória, é utilizada para determinar a classe de cada linha.
Mapeamento objeto-relacional (9/31) JPA 2 (13/43) Mapeamento objeto-relacional (9/31) Anotando Herança (3/8) Estratégia Single Table (2/3) Co-anotação @DiscriminatorColumn( name="<nome-da-coluna>", discriminatorType=DiscriminatorType.STRING) Determina a coluna discriminatória da classe de cada linha; Aplicação Antes da definição da superclasse mais genérica.
Mapeamento objeto-relacional (10/31) JPA 2 (14/43) Mapeamento objeto-relacional (10/31) Anotando Herança (4/8) Estratégia Single Table (3/3) Co-anotação @DiscriminatorValue( "<valor-discriminatório>") Determina o valor da coluna discriminatória para classe anotada em questão; Aplicação Antes da definição de cada classe não-abstrata da hierarquia.
Mapeamento objeto-relacional (11/31) JPA 2 (15/43) Mapeamento objeto-relacional (11/31) Anotando Herança (5/8) Estratégia Joined Subclasses (1/2) @Inheritance( strategy=InheritanceType.JOINED) Aplicação Antes da definição da superclasse mais genérica. Cada classe na hierarquia tem sua tabela; Os atributos ocorrem apenas na tabela da classe em que foram declarados; Uma subclasse sabe sua superclasse imediata por meio de uma chave estrangeira.
Mapeamento objeto-relacional (12/31) JPA 2 (16/43) Mapeamento objeto-relacional (12/31) Anotando Herança (6/8) Estratégia Joined Subclasses (2/2) Co-anotação @PrimaryKeyJoinColumn( name="<col-subclasse-chavestrangeira-superclasse>", referencedColumnName="<col-superclasse>") Aplicação Antes da definição de cada subclasse não-abstrata; Determina, na tabela da subclasse, qual a coluna (discriminada no item name) que serve de chave estrangeira para uma coluna da superclasse (discriminada no item referencedColumnName).
Mapeamento objeto-relacional (13/31) JPA 2 (17/43) Mapeamento objeto-relacional (13/31) Anotando Herança (7/8) Estratégia Mapped Superclass @MappedSuperclass Apenas as subclasses possuem tabelas; Os atributos da superclasse anotada são replicados para todas as tabelas das subclasses; Aplicação Antes da definição da superclasse que não deve possuir tabela.
Mapeamento objeto-relacional (14/31) JPA 2 (18/43) Mapeamento objeto-relacional (14/31) Anotando Herança (8/8) Limitação Em uma mesma hierarquia de superclasses e subclasses (mesma linhagem), não se podem misturar estratégias diversas de mapeamento de herança.
JPA 2 (19/43) Mapeamento objeto-relacional (15/31) Anotando Relacionamentos (1/16) Conceitos Básicos (1/4) Cascateamento de operações (1/3) Operar sobre uma entidade implica em propagar a operação sobre as entidades relacionadas;
Mapeamento objeto-relacional (16/31) JPA 2 (20/43) Mapeamento objeto-relacional (16/31) Anotando Relacionamentos (2/16) Conceitos Básicos (2/4) Cascateamento de operações (2/3) Operações refresh(); persist(); remove(); merge().
Mapeamento objeto-relacional (17/31) JPA 2 (21/43) Mapeamento objeto-relacional (17/31) Anotando Relacionamentos (3/16) Conceitos Básicos (3/4) Cascateamento de operações (3/3) Tipos REFRESH - refresh() propagado; PERSIST - persist() propagado; REMOVE - remove() propagado; MERGE - merge() propagado; DETACH - destacamento propagado; ALL - todas as operações propagadas.
JPA 2 (22/43) Mapeamento objeto-relacional (18/31) Anotando Relacionamentos (4/16) Conceitos Básicos (4/4) Carregamento de Entidades Relacionadas na Memória (fetch) Tipos EAGER – entidades relacionadas são carregadas em memória juntamente com a entidade recuperada do BD. LAZY – entidades relacionadas são carregadas em memória somente quanto acessadas por algum método Java.
JPA 2 (23/43) Mapeamento objeto-relacional (19/31) Anotando Relacionamentos (5/16) @OneToOne (1/3) Aplicação Antes da declaração da entidade relacionada. Formato @OneToOne( cascade = CascadeType.ALL | {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE, (...)}, fetch = [FetchType.EAGER | FetchType.LAZY], optional = [true | false] )
JPA 2 (24/43) Mapeamento objeto-relacional (20/31) Anotando Relacionamentos (6/16) @OneToOne (2/3) Unidirecional Apenas o lado que acessa a outra entidade pode ser anotado; Co-anotação @JoinColumn(name = “<col-chave-estrangeira>”, referencedColumnName = “<col-tabela-relacionada>”) Aplicação Antes da declaração da entidade relacionada. Determina, na tabela da entidade corrente, qual a coluna (discriminada no item name) que serve de chave estrangeira para uma coluna da outra entidade relacionada (discriminada no item referencedColumnName).
JPA 2 (25/43) Mapeamento objeto-relacional (21/31) Anotando Relacionamentos (7/16) @OneToOne (3/3) Bidirecional Lado que possui a coluna com a chave estrangeira recebe a anotação @OneToOne e co-anotação @JoinColumn; Outro lado recebe apenas a anotação @OneToOne, com item mapped-by = “<nome-atributo-na-outra-entidade>” Exemplo @OneToOne( cascade = CascadeType.ALL, fecth = FetchType.LAZY, optional = true, mappedBy = “<nome-atributo>” )
JPA 2 (26/43) Mapeamento objeto-relacional (22/31) Anotando Relacionamentos (8/16) @OneToMany (1/3) Aplicação Antes da declaração da coleção da entidade relacionada. Formato @OneToMany( cascade = CascadeType.ALL | {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE, (...)}, fetch = [FetchType.EAGER | FetchType.LAZY] )
JPA 2 (27/43) Mapeamento objeto-relacional (23/31) Anotando Relacionamentos (9/16) @OneToMany (2/3) Unidirecional Apenas o lado que acessa a coleção da outra entidade pode ser anotado; Co-anotação @JoinColumn(name = “<col-chave-estrangeira-tabela-relacionada>”, referencedColumnName = “<col-tabela-entidade-corrente>”) Aplicação Antes da declaração da coleção da entidade relacionada. Determina, na tabela da entidade relacionada, qual a coluna (discriminada no item name) que serve de chave estrangeira para uma coluna da entidade corrente (discriminada no item referencedColumnName).
JPA 2 (28/43) Mapeamento objeto-relacional (24/31) Anotando Relacionamentos (10/16) @OneToMany (3/3) Bidirecional Apenas o lado que acessa a coleção da outra entidade pode ser anotado; Anotação @OneToMany é acrescida com o item mapped-by = “<nome-atributo-na-outra-entidade>” Exemplo @OneToMany( cascade = CascadeType.ALL, fecth = FetchType.LAZY, mappedBy = “<nome-atributo>” )
JPA 2 (29/43) Mapeamento objeto-relacional (25/31) Anotando Relacionamentos (11/16) @ManyToOne (1/2) Aplicação Antes da declaração da entidade relacionada. Formato @ManyToOne( cascade = CascadeType.ALL | {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE, (...)}, fetch = [FetchType.EAGER | FetchType.LAZY], optional = [true | false] )
JPA 2 (30/43) Mapeamento objeto-relacional (26/31) Anotando Relacionamentos (12/16) @ManyToOne (2/2) Co-anotação @JoinColumn(name = “<col-chave-estrangeira>”, referencedColumnName = “<col-tabela-relacionada>”) Aplicação Antes da declaração da entidade relacionada. Determina, na tabela da entidade corrente, qual a coluna (discriminada no item name) que serve de chave estrangeira para uma coluna da outra entidade relacionada (discriminada no item referencedColumnName).
JPA 2 (31/43) Mapeamento objeto-relacional (27/31) Anotando Relacionamentos (13/16) @ManyToMany (1/4) Aplicação Antes da declaração da coleção da entidade relacionada. Formato @ManyToMany( cascade = CascadeType.ALL | {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE, (...)}, fetch = [FetchType.EAGER | FetchType.LAZY] )
JPA 2 (32/43) Mapeamento objeto-relacional (28/31) Anotando Relacionamentos (14/16) @ManyToMany (2/4) Lado Dominante e Lado Inverso Lado Dominante (owner) Lado em que a propagação de operações é efetuada. Lado Inverso (inverse) Lado em que a propagação de operações é ignorada.
JPA 2 (33/43) Mapeamento objeto-relacional (29/31) Anotando Relacionamentos (15/16) @ManyToMany (3/4) Unidirecional Apenas o lado dominante pode ser anotado; Co-anotação @JoinTable(name = “<nome-tabela-associativa>”, joinColumns = @JoinColumn(name = “<nome-coluna-chavestrangeira-lado-dominante>”), inverseJoinColumns = @JoinColumn(name = “<nome-coluna-chavestrangeira-lado-inverso) ) Aplicação Antes da declaração da coleção da entidade relacionada. Determina o conteúdo da tabela associativa (cujo nome está discriminado no item name) que guarda chaves estrangeiras para colunas das entidades relacionadas; Colunas do lado dominante discriminadas pelo item joinColumns; Colunas do lado inverso discriminadas pelo item inverseJoinColumns.
JPA 2 (34/43) Mapeamento objeto-relacional (30/31) Anotando Relacionamentos (16/16) @ManyToMany (4/4) Bidirecional Lado dominante recebe a anotação @ManyToMany e co-anotação @JoinTable; Lado inverso recebe apenas a anotação @ManyToMany, com item mapped-by = “<nome-coleção-atributo-no-outro-lado>” Exemplo @ManyToMany( cascade = CascadeType.ALL, fecth = FetchType.LAZY, mappedBy = “<nome-coleção-atrib>” )
JPA 2 (35/43) Mapeamento objeto-relacional (31/31) Referência oficial do Hibernate http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html
JPA 2 (36/43) Ajuste dos JavaBeans JavaBeans Classes Java do domínio do problema; Atributos de acesso privado; Métodos getters e setters para todos os atributos; Método construtor sem parâmetros. Implementação da interface java.io.Serializable Objetos podem ser convertidos em streams de bytes Transferência; Persistência. Inclusão do atributo serialVersionUID Número de controle da versão da classe do objeto eventualmente serializado.
JPA 2 (37/43) Configuração da Persistência (1/3) Arquivo persistence.xml (1/2) Arquivo de configuração do JPA; Define a “unidade de persistência” das entidades Controle transacional utilizado (transaction-type) JTA (servidor de aplicação contém biblioteca que controla as transações); RESOURCE_LOCAL (desenvolvedor define classe de controle transacional, relatada no arquivo beans.xml). Provider JPA utilizado; Lista de entidades persistidas; Propriedades da conexão com o BD Driver de acesso; Usuário; Senha; URL; Etc.
JPA 2 (38/43) Configuração da Persistência (2/3) Arquivo persistence.xml (2/2) Exemplo <?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance“ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name=“bookmark-ds" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>pessoal.treinamento.domain.Bookmark</class> <properties> <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" /> <property name="javax.persistence.jdbc.user" value="sa" /> <property name="javax.persistence.jdbc.password" value="" /> <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:hsql:." /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.hbm2ddl.auto" value="create-drop" /> </properties> </persistence-unit> </persistence>
JPA 2 (39/43) Configuração da Persistência (3/3) Arquivo beans.xml Biblioteca de beans utilizados no projeto; Tag <alternatives> Possibilidade de incluir bean utilizado no controle transacional. Exemplo <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance“ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> <alternatives> <class>br.gov.frameworkdemoiselle.transaction.JPATransaction</class> </alternatives> </beans>
JPA 2 (40/43) Conexão com o SGBD Oracle (1/3) Instalação da API conectora (1/2) Download no sítio da Oracle, com necessidade de cadastramento Biblioteca proprietária; http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html
JPA 2 (42/43) Conexão com o SGBD Oracle (2/3) Instalação da API conectora (2/2) Adição à gestão do Maven Cópia do jar da API para a pasta de bibliotecas do projeto src/main/webapp/WEB-INF/lib Inclusão da dependência no POM do projeto Exemplo <dependencies> (...) <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc</artifactId> <version>14</version> <scope>system</scope> <systemPath>${basedir}/src/main/webapp/WEB-INF/lib/ojdbc14.jar </systemPath> </dependency> </dependencies>
JPA 2 (43/43) Conexão com o SGBD Oracle (3/3) Configuração da JPA Ajuste do arquivo persistence.xml Exemplo <properties> <property name="javax.persistence.jdbc.driver“ value="oracle.jdbc.OracleDriver" /> <property name="javax.persistence.jdbc.user" value=“usuario" /> <property name="javax.persistence.jdbc.password" value=“senha" /> <property name="javax.persistence.jdbc.url“ value="jdbc:oracle:thin:@127.0.0.1:1521:orcl" /> (...) </properties>