Hibernate - Anotações
Até agora você viu como o Hibernate usa arquivo de mapeamento XML para a transformação de dados de POJO em tabelas de banco de dados e vice-versa. As anotações do Hibernate são a forma mais recente de definir mapeamentos sem o uso de arquivo XML. Você pode usar anotações além ou como uma substituição dos metadados de mapeamento XML.
Hibernate Annotations é a maneira poderosa de fornecer os metadados para o mapeamento de Objetos e Tabelas Relacionais. Todos os metadados são inseridos no arquivo POJO java junto com o código, o que ajuda o usuário a entender a estrutura da tabela e o POJO simultaneamente durante o desenvolvimento.
Se você pretende tornar seu aplicativo portátil para outros aplicativos ORM compatíveis com EJB 3, deve usar anotações para representar as informações de mapeamento, mas, ainda assim, se quiser maior flexibilidade, deve optar por mapeamentos baseados em XML.
Configuração do ambiente para anotação do Hibernate
Em primeiro lugar, você deve certificar-se de que está usando o JDK 5.0, caso contrário, será necessário atualizar seu JDK para o JDK 5.0 para aproveitar as vantagens do suporte nativo para anotações.
Em segundo lugar, você precisará instalar o pacote de distribuição de anotações do Hibernate 3.x, disponível no sourceforge: ( Baixe o Hibernate Annotation ) e copiehibernate-annotations.jar, lib/hibernate-comons-annotations.jar e lib/ejb3-persistence.jar da distribuição de anotações do Hibernate para seu CLASSPATH.
Exemplo de classe anotada
Como mencionei acima, ao trabalhar com o Hibernate Annotation, todos os metadados são agrupados no arquivo POJO java junto com o código, isso ajuda o usuário a entender a estrutura da tabela e POJO simultaneamente durante o desenvolvimento.
Considere que vamos usar a seguinte tabela EMPLOYEE para armazenar nossos objetos -
create table EMPLOYEE (
id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);
A seguir está o mapeamento da classe Employee com anotações para mapear objetos com a tabela EMPLOYEE definida -
import javax.persistence.*;
@Entity
@Table(name = "EMPLOYEE")
public class Employee {
@Id @GeneratedValue
@Column(name = "id")
private int id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "salary")
private int salary;
public Employee() {}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}
}
O Hibernate detecta que a anotação @Id está em um campo e assume que deve acessar as propriedades de um objeto diretamente através dos campos em tempo de execução. Se você colocou a anotação @Id no método getId (), habilitaria o acesso às propriedades por meio dos métodos getter e setter por padrão. Portanto, todas as outras anotações também são colocadas em campos ou métodos getter, seguindo a estratégia selecionada.
A seção a seguir explicará as anotações usadas na aula acima.
@Entity Annotation
As anotações padrão EJB 3 estão contidas no javax.persistencepacote, então importamos este pacote como a primeira etapa. Em segundo lugar, usamos o@Entity anotação para a classe Employee, que marca essa classe como um bean de entidade, portanto, deve ter um construtor sem argumento que seja visível com pelo menos escopo protegido.
@Table Annotation
A anotação @Table permite que você especifique os detalhes da tabela que será usada para persistir a entidade no banco de dados.
A anotação @Table fornece quatro atributos, permitindo que você substitua o nome da tabela, seu catálogo e seu esquema, e impõe restrições exclusivas às colunas da tabela. Por enquanto, estamos usando apenas o nome da tabela, que é EMPLOYEE.
Anotações @Id e @GeneratedValue
Cada bean de entidade terá uma chave primária, que você anota na classe com o @Idanotação. A chave primária pode ser um único campo ou uma combinação de vários campos, dependendo da estrutura da tabela.
Por padrão, a anotação @Id determinará automaticamente a estratégia de geração de chave primária mais apropriada a ser usada, mas você pode substituir isso aplicando o @GeneratedValue anotação, que leva dois parâmetros strategy e generatorque não vou discutir aqui, vamos usar apenas a estratégia de geração de chave padrão. Permitir que o Hibernate determine qual tipo de gerador usar torna seu código portátil entre bancos de dados diferentes.
@Column Annotation
A anotação @Column é usada para especificar os detalhes da coluna para a qual um campo ou propriedade será mapeado. Você pode usar a anotação de coluna com os seguintes atributos mais comumente usados -
name atributo permite que o nome da coluna seja especificado explicitamente.
length atributo permite o tamanho da coluna usada para mapear um valor, particularmente para um valor String.
nullable atributo permite que a coluna seja marcada como NOT NULL quando o esquema é gerado.
unique atributo permite que a coluna seja marcada como contendo apenas valores únicos.
Criar classe de aplicativo
Por fim, criaremos nossa classe de aplicativo com o método main () para executar o aplicativo. Usaremos este aplicativo para salvar alguns registros de funcionários e, em seguida, aplicaremos operações CRUD nesses registros.
import java.util.List;
import java.util.Date;
import java.util.Iterator;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class ManageEmployee {
private static SessionFactory factory;
public static void main(String[] args) {
try {
factory = new AnnotationConfiguration().
configure().
//addPackage("com.xyz") //add package if used.
addAnnotatedClass(Employee.class).
buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
ManageEmployee ME = new ManageEmployee();
/* Add few employee records in database */
Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
Integer empID3 = ME.addEmployee("John", "Paul", 10000);
/* List down all the employees */
ME.listEmployees();
/* Update employee's records */
ME.updateEmployee(empID1, 5000);
/* Delete an employee from the database */
ME.deleteEmployee(empID2);
/* List down new list of the employees */
ME.listEmployees();
}
/* Method to CREATE an employee in the database */
public Integer addEmployee(String fname, String lname, int salary){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try {
tx = session.beginTransaction();
Employee employee = new Employee();
employee.setFirstName(fname);
employee.setLastName(lname);
employee.setSalary(salary);
employeeID = (Integer) session.save(employee);
tx.commit();
} catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
return employeeID;
}
/* Method to READ all the employees */
public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator = employees.iterator(); iterator.hasNext();){
Employee employee = (Employee) iterator.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
}
tx.commit();
} catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
/* Method to UPDATE salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Employee employee = (Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
} catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
/* Method to DELETE an employee from the records */
public void deleteEmployee(Integer EmployeeID){
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Employee employee = (Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
} catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}
Configuração de banco de dados
Agora vamos criar hibernate.cfg.xml arquivo de configuração para definir os parâmetros relacionados ao banco de dados.
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name = "hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name = "hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- Assume students is the database name -->
<property name = "hibernate.connection.url">
jdbc:mysql://localhost/test
</property>
<property name = "hibernate.connection.username">
root
</property>
<property name = "hibernate.connection.password">
cohondob
</property>
</session-factory>
</hibernate-configuration>
Compilação e execução
Aqui estão as etapas para compilar e executar o aplicativo mencionado acima. Certifique-se de ter definido PATH e CLASSPATH apropriadamente antes de prosseguir para a compilação e execução.
Exclua o arquivo de mapeamento Employee.hbm.xml do caminho.
Crie o arquivo de origem Employee.java conforme mostrado acima e compile-o.
Crie o arquivo de origem ManageEmployee.java conforme mostrado acima e compile-o.
Execute o binário ManageEmployee para executar o programa.
Você obteria o seguinte resultado e os registros seriam criados na tabela EMPLOYEE.
$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........
First Name: Zara Last Name: Ali Salary: 1000
First Name: Daisy Last Name: Das Salary: 5000
First Name: John Last Name: Paul Salary: 10000
First Name: Zara Last Name: Ali Salary: 5000
First Name: John Last Name: Paul Salary: 10000
Se você verificar sua tabela EMPLOYEE, ela deve ter os seguintes registros -
mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 29 | Zara | Ali | 5000 |
| 31 | John | Paul | 10000 |
+----+------------+-----------+--------+
2 rows in set (0.00 sec
mysql>