terça-feira, 19 de junho de 2007

Hibernate Composite Id...

Bom dia galera, depois de algum tempo hoje irei postar um exemplo de hibernate usando chave composta....

Primeiramente vamos a tabela:

Permissoes
usuario #
grupo #
centro_de_custo #

# chaves compostas

Agora vamos mapear isso usando hibernate annotations com jpa.

Classe Permissoes:

@Entity
@Table(name = "permissoes")
@IdClass(PermissoesPk.class)
public class Permissoes implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@Column(name = "usuario")
private String usuario;

@Id
@Column(name = "grupo")
private String grupo;

@Id
@Column(name = "centro_de_custo")
private int centroDeCusto;

// gets e sets

}

Criaremos então uma nova classe que contém essas chaves:

@Embeddable
public class PermissoesPk implements Serializable {

private static final long serialVersionUID = 1L;

private String grupo;

private String usuario;

private int centroDeCusto;

// gets e sets

}

De acordo com a documentação para fazer um mapeamento de chaves compostas a classe que contém o nome com final PK deve sobreescrever o método equals e hascode e também implementar Serializable.

Na documentação do hibernate tem outras duas formas de mapeamento usando @Id ou @EmbeddedId.

Veja este exemplo usando @Id:

@Entity
public class RegionalArticle implements Serializable {

@Id
public RegionalArticlePk getPk() { ... }
}

@Embeddable
public class RegionalArticlePk implements Serializable { ... }

Veja este exemplo usando @EmbeddedId:

@Entity
public class RegionalArticle implements Serializable {

@EmbeddedId
public RegionalArticlePk getPk() { ... }
}

public class RegionalArticlePk implements Serializable { ... }


esses exemplos são para guardar, futuramentem precisarei com ctz.

mais exemplos siga:
http://www.hibernate.org/hib_docs/annotations/reference/en/html_single/#d0e1659

[]'s

terça-feira, 12 de junho de 2007

Tutorial Abstract Factory Method...

Bom dia, hoje postarei algo sobre o padrão Abstract Factory Method, vamos lá...

Design Pattern: São uma coleção de padrões de desenho de software, que são soluções de problemas ocorridos no dia a dia de desenvolvimento de um software (são boas idéias).

Abstract Factory Method: este padrão é bem recomendado como por exemplo quando você utiliza vários tipos de bancos de dados em seu projeto, ele é uma fábrica que retorna uma das várias fábricas.



Vamos para um exemplo prático: Criarei uma factory para retornar um dos vários objetos DAO's do meu projeto, considere o seguinte diagrama:










Segue a implementação no código deste diagrama:

Esta classe abstrata é a Factory que retorna instancia de outras factories:

public abstract class DAOFactory {

public abstract UserDAO getUserDAO();

public static DAOFactory getInstance(int wichFactory) {
switch (wichFactory) {
case 1:
return new MySqlUserDAOFactory();
case 2:
return new PostgresUserDAOFactory();
default:
return null;
}
}
}


Factory para MySql
public class MySqlUserDAOFactory extends DAOFactory {

@Override
public UserDAO getUserDAO() {
return new MySqlUserDAO();
}
}


Factory para Postgres
public class PostgresUserDAOFactory extends DAOFactory {
@Override
public UserDAO getUserDAO() {
return new PostgresUserDAO();
}
}


Interface UserDAO, contém os métodos que os DAO's devem implementar.
public interface UserDAO {
public void save(Object o);
}


DAO para MySQL
public class MySqlUserDAO implements UserDAO {
public void save(Object o) {
// TODO Auto-generated method stub
}
}


DAO para Postgres
public class PostgresUserDAO implements UserDAO {
public void save(Object o) {
// TODO Auto-generated method stub
}
}


Vamos ver como chamariamos as nossas classes:

public static void main(String[] args) {
DAOFactory daoFactory = DAOFactory.getInstance(1);
// retorna a factory para MySql
UserDAO userDAO = daoFactory.getUserDAO();
userDAO.save(new Object());

DAOFactory daoFactory2 = DAOFactory.getInstance(2);
// retorna a factory para Postgres
UserDAO userDAO2 = daoFactory2.getUserDAO();
userDAO2.save(new Object());
}


Com isso a nossa implementação termina, um detalhe importante que deve-se notar é que se por um acaso um dia sua empresa decicidir incluir o oracle basta apenas criar uma nova factory OracleUserDAOFactory e estender a classe DAOFactory e pronto, com esse padrão fica muito flexível incluir e excluir qualquer nova implementação.



É isso ae...

[]'s

Tutorial Hibernate...


Eae galera.....

Vou começar com um breve tutorial de Hibernate:

Primeiramente estarei explicando alguns conceitos que estão relacionados com frameworks de persistência:

Um framework de persistência deve prover algumas funcionalidades e serviços para ser considerável a utilização do mesmo, citarei alguns seviços e funcionalidades referente a framework de persistência, em nosso exemplo do Hibernate.


· Controle transacional: o framework deve permitir rollback quando ocorrer algum erro e commit quando o objeto for persistido com sucesso.
· Identificadores de objeto: cada objeto de ter um identificador único para ser relacionado com o registro correspondente. Um OID (Object Identifier) garante que o objeto não se duplicará.
· Mapeamento O-R: se não utilizar um banco de dados orientado a objetos deve existir um mapeamento de objeto relacional entre a classe e a tabela do banco de dados isso é um dos requisitos principais de um framework de persistência de objetos é responsável por transformar uma representação de dados não orientada a objetos em um objeto e por armazenar um objeto persistente no seu mecanismo de persistência como um banco de dados, por exemplo.
· Cache: com o uso do cache o objeto é colocado em uma memória local para obter um maior desempenho, quando for necessário o uso desse objeto basta apenas buscá-lo na memória local que ele foi colocado agilizando todo o processo.
· Consultas sob demanda: os objetos são carregados apenas quando necessário evitando que registros sejam recuperados, todos de uma vez só. Com isso reduz a carga de informações na rede, se sua aplicação for utilizada através de internet este recurso garante um melhor desempenho.
· Proxy: é um objeto proxy de forma que o usuário e o serviço de persistência conseguem identificar. Assim quando um objeto for carregado apenas as informações definidas pelo objeto proxy serão recuperadas.
· Queries: utilizado para consultas mais complexas, isto pode ser feito através de OQL (Object Query Language) que é uma linguagem de consulta a banco de dados orientados a objetos ou também embutindo código SQL (Structure Query Language) na aplicação, pois isto não é muito recomendado porque acopla a estrutura do banco de dados com a sua aplicação.
. Portabilidade: um framework de persistência deve ser compatível com vários tipos de mecanismos de persistência de dados e também disponibilizar diversas maneiras de conexão, sendo isso muito importante porque quando for necessário trocar de mecanismo de persistência de dados não é necessário mudar toda sua aplicação.



Então o que é Hibernate ? Quais as vantagens de utilizar ? Quais desvantagens ?

Hibernate é um framework de persistência que permite a utilização de banco de dados relacional, porém, trabalhando com objetos, falar isso apenas é muito pouco
para o que o Hibernate pode fazer...
Uma das vantagens de utilizá-lo é que o desenvolvimento de aplicação se torna mais rápido, por não ter que escrever códigos e mais códigos SQL da vida... A idéia do
hibernate é encapsular todo o código SQL Jdbc por tráz de sua implementação, ficando transparente para o desenvolvedor.
Uma das desvantagens do hibernate é que para criar algumas queries bem complexas deve-se perder um tempo maior estudando as Criterias da vida!!!! São um pouco
complexas...
Outra desvantagen que eu considero é colocar milhões de jar's em sua aplicação, porém uma vez configurado não é preciso mexer novamente.



Exemplo:

Tudo isso:
INSERT INTO agendaadmissao (codigoagenda, nomecandidato, matriculacoordenador, codigocurso, data, status)
VALUES("1", "João da Silva Dias", "p100", "2", "2007-06-28 19:40:00", "P");

por isso:
session.save(objeto); // uau em uma linha!!!!

O hibernate permite ainda ir mais além, com apenas essa linha citada acima ele salva também todos os relacionamentos, para isso basta apenas configurar
uma propriedade chamada de Cascade, temos alguns tipos de cascade como:
ALL = persiste o objeto pai mais todos os filhos, cuidado ao utilizar pois se você deletar um objeto pai e tiver com essa propriedade tudo vai pro espaço...
None = este é o default, as operações relacionadas ao objeto pai apenas sofrerão alguma mudança nele mesmo em mais ninguém.
Save Update = onde o objeto pai pode salvar ou atualizar os filhos.
Persist = Apenas para operações de save.
All delete orphan = a partir do objeto pai ele deleta os filhos.



O Hibernate possui algumas interfaces importantes que vale a pena ser descrito, então vamos lá:


1º Interface de sessão (Session): Sessão (Session) é a interface primária do Hibernate, é de peso leve e mais fácil de criar e destruir. O objeto Session, por ser leve, ajudará na sua aplicação porque há uma grande necessidade de criar e destruir objetos Session há quase todo instante. As sessões não são Threadsafe, ou seja, uma Sessão do Hibernate é algo entre conexão e transação. Pode ser um armazenamento ou coleção de objetos numa única unidade de trabalho, podendo ser chamada de gerente de persistência, que faz a interface com operações relacionadas com a persistência, armazenando e recuperando objetos.

2º Interface SessionFactory: a interface SessionFactory não é considerada peso leve, sendo compartilhada entre muitas threads. Para a SessionFactory há um único aplicativo, criado na inicialização. Se seu aplicativo for acessar bancos de dados múltiplos usando Hibernate, é necessário uma SessionFactory para cada banco de dados. Esta interface controla dados armazenados e que foram lidos em uma unidade de trabalho, podendo ser reutilizados em uma unidade futura. Isso se o mapeamento de classe especificar o armazenamento do segundo nível. Geralmente a SessionFactory armazena instruções SQL (Structured Query Language), e outros metadados que são executados em tempo de execução.

3º Interface de Configuração: Segundo Bauer, King (2005, p. 39), a interface de configuração vai ser a primeira a ser encontrada quando você usar o Hibernate. Essa interface é muito importante porque depois de configurada, o Hibernate vai criar o SessionFactory.

4º Interface de Transação: é uma API (Application Programming Interface) opcional do Hibernate uma transação permite controlar os limites das transações usando uma API consistente com isso tornam-se portáveis os aplicativos do Hibernate com ambientes diferentes de execução.

5º Consulta e critérios de interfaces: a interface de consulta e critério serve para executar consultas no banco de dados. As consultas são feitas “escritas” em SQL(Structured Query Language) de seu banco de dados, para ligar parâmetros de consultas e limitar o número de resultados devolvidos pela consulta.


Vamos para o que interessa, criar um exemplo simples:

Vamos supor que estamos desenvolvendo um cadastro de cliente, (por enquanto, sem relacionamento):

Temos então:

Tabelas:

DROP TABLE IF EXISTS `cliente`;
CREATE TABLE `cliente` (
`nome` varchar(30) default NULL,
`id_cliente` int(9) NOT NULL auto_increment,
PRIMARY KEY (`id_cliente`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;


Para cada tabela dessa temos um Objeto chamado de Objeto ORM (Mapeamento de Objeto Relacional), ou seja o mapeamento das suas classes.

Essa é uma classe simples JavaBean com método get e set, a partir desta classe que faremos o mapeamento:


/**
* @author alberto ribeiro
*/
public class Cliente {
private int id;
private String nome;
get's e set's
}


Para a criação da aplicação alguns jar's terão que ser incluidos no classpath do projeto:

Hibernate3.jar: core do Hibernate.
c3p0-0.8.4.5.jar: Pool de conexão básico para executar testes unitários.
cglib-full-2.0.2.jar: biblioteca geradora de código para criação de proxies para classes persitentes.
dom4j-1.4.jar: biblioteca XML para parse de arquivos de configuração e mapeamento.
ecache-0.9.jar: cachê puro em Java, cachê padrão do Hibernate.
jta.jar: Java Transaction API.
commons-loging-1.0.4.jar: base para o mapeamento de produtos objeto relacional
commons-collections-2.1.1: contém as listas como bag, array list entre outros tipos de listas.
ojdbc.jar: jar do fabricante do bando de dados


Abaixo o mapeamento ORM, da classe Cliente, chamaremos de ClienteORM.hbm.xml:




Neste mapeamento vale ressaltar algumas propridades:

class name = é o relacionamento da tabela com a classe, sendo que o atributo name deve conter o nome completo do objeto incluindo o pacote e o atributo table deve conter o nome da tabela.

table = nome da tabela referente a classe.

id = nome do campo id dentro da classe cliente

column = "id_cliente" = referente ao nome da coluna no banco de dados.

type = o tipo da propriedade no caso id_cliente é um int.

generator = referente ao esquema de geração de ID no banco de dados, o native indica que o banco se encarregará de gerar este número sequencial.

property = a propriedade da classe, exemplo: nome e seu tipo string.


Depois de ter as classes mapeadas em um arquivo xml, temos então que configurar o hibernate.cfg.xml que será responsável
por algumas propiedades importantes de configuração:



Vale ressaltar as seguintes propridades:

dialect = responsável pela geração das intruções SQL de acordo com cada Bando de Dados, ele representa a linguagem que será gerada as queries da aplicação para o banco.

connection.url = a url é específica ao banco de dados utilizado, na url passamos como parâmetros o IP da máquina ou o nome do servidor, porta e o nome da base de dados. Usuário e senha são do banco de dados

connection.driver_class = O nome do driver que estamos utilizando no caso MySQL.

connection.username = username no banco de dados.

connection.password = senha no banco de dados.

show_sql = se estiver marcado como true, todas as queries geradas serão impressas no console.

mapping resource = local onde estão os mapeamentos XML referente as classes.


Criaremos agora uma classe utilitária responsável por criar as famosas Session's do hibernate:


public class HibernateUtil {

private static SessionFactory sessionFactory;

private static Session session;

private static Logger logger = Logger.getLogger(HibernateUtil.class);

static {
sessionFactory = new Configuration().configure().buildSessionFactory();
// obs o arquivo hibernate.cfg.xml deve estar na pasta src, o hibernate procura ela la dentro
// caso queira ficar em outro lugar deve mudar aqui: new Configuration().configure("nome do pacote onde está o //arquivo").buildSessionFactory();


if (logger.isDebugEnabled()) {
logger.info("Criando a session factory");
}
}

public static Session getCurrentSession() {
if (session == null || !session.isOpen() || !session.isConnected()) {
session = ((SessionFactory) sessionFactory).openSession();
}
return session;
}

public static void closeSession() {
session.close();
}

}



Criando nosso DAO, mas antes uma breve explicação: DAO é um padrão de projetos que veio para separar a camada de modelos de dados referente a banco de dados dos modelos de objetos, caso o mecanismo de persistencia troque, modifica-se a camada DAO.
Dentro desse DAO ficará os métodos CRUD, ou seja, create, retrieve, update e delete.

ClienteDAO:

public class ClienteDAO{

public void save(Object object) throws AcessoBaseDeDadosException {
if (object == null) {
throw new AcessoBaseDeDadosException(
"O objeto à ser salvo está nulo.");
}

try {
HibernateUtil.getCurrentSession().save(object);
} catch (HibernateException e) {
throw new AcessoBaseDeDadosException("Erro persistindo o objeto: "
+ object.getClass().toString(), e);
} catch (Exception e) {
throw new AcessoBaseDeDadosException("Erro persistindo o objeto: "
+ object.getClass().toString(), e);
}
}
}

A estrutura do projeto ficou assim:

Persistencia
src
br/edu/persistencia/common/
   Cliente.java
   ClienteORM.hbm.xml
br/edu/persistencia/dao/
   ClienteDAO.java
br/edu/persistencia/util/
   HibernateUtil.java
hibernate.cfg.xml
lib
   Todos os jar's citados acima.

Podemos agora fazer o teste:

public class Teste {

public static void main(String[] args) throws Exception {
ClienteDAO dao = new ClienteDAO();

Cliente cliente = new Cliente();
cliente.setNome("Alberto");

Session session = HibernateUtil.getCurrentSession(); // Pegando uma sessão, caso esteja em aberto ele apenas //retorna uma sessão corrente
Transaction tx = session.begintransaction(); // iniciando uma transação para poder inserir no banco de dados
dao.save(cliente); // chamando o método save da classe DAO
tx.commit(); // finalizando a transação.
session.close(); // fechando a sessão com o banco.
}
}


É isso ai então, depois testar, mas, acredito que esteja correto, qualquer dúvida mande!!!! Este foi o primeiro, não sei se está bom mas com o tempo isso melhora...


[]'s

sexta-feira, 8 de junho de 2007

Boa tarde pessoal, hoje começa uma nova etapa...

Estarei começando a relatar alguns erros ocorridos no dia a dia de desenvolvimento e postando é claro a solução né!!! rssss

Estarei postando alguns tutoriais também...

Aguardem...

Prometo me dedicar!!!