Back-End

5 jul, 2013

CRUD com Hibernate e Spring framework

Publicidade

Olá, pessoal!

No artigo de hoje vamos fazer um CRUD usando Spring com Hibernate. Nos últimos artigos vimos as coisas de forma separada, para entendermos o funcionamento bem específico. Vou considerar que você tenha lido os artigos anteriores e aquilo que já foi explicado; logo, não irei repetir para evitar que o artigo fique longo. Vou só ressaltar o que for importante e relevante para que você entenda.

O nosso cenário

Será bem simples, funcional e o mais direto possível. O cenário é bem trivial: uma livraria tem vários e um livro está para uma categoria. Uma categoria pode ter vários livros.

Então, vamos exercitar o relacionamento @OneToMany do hibernate e a integração do Hibernate com Spring. E para completar, faremos a injeção de dependência usando Annotations.

Desenvolvimento

A seguir, como ficará o nosso projeto:

springcrudbookproject

1. Crie um java project e os respectivos packages;

2. Adicione as bibliotecas do Spring Framework 3.x, Hibernate 3.x e MySql 5.x;

3. Crie a interface que terá o CRUD:

public interface BookStore {
 void saveOrUpdate(Book book); 
 void delete(Book book);
 Book findById(Long id); 
}

4. Agora criaremos a classe que vai implementar a interface:

@Repository
public class BookStoreDAO implements BookStore {

 @Autowired
 private HibernateTemplate hibernateTemplate;
@Override
 public Book findById(Long id) {
 return hibernateTemplate.get(Book.class, id);
 }
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
 this.hibernateTemplate = hibernateTemplate;
 }
public HibernateTemplate getHibernateTemplate() {
 return hibernateTemplate;
 }
@Override
 public void saveOrUpdate(Book book) {
 hibernateTemplate.saveOrUpdate(book);
 }
@Override
 public void delete(Book book) {
 hibernateTemplate.delete(book);
 }
}

Até aqui nada de especial, exceto a anotação @Autowired que colocamos para informar ao Spring que aquele atributo é dependecy injection e que é controlado por ele. Quando criarmos o nosso arquivo de configuração do Spring, vamos dizer para ele como olhar para as annotations. E a anotação @Repository é para dizer ao Spring que essa classe é um DAO.

Agora, vamos criar a classe CategoryDAO, que vai persistir às categorias:

@Repository
public class CategoryDAO {
 @Autowired
 private HibernateTemplate hibernateTemplate;

 public void saveOrUpdate(Category category){
 hibernateTemplate.saveOrUpdate(category);
 }
}

Por enquanto, essa classe não vai compilar, porque ainda não criamos a classe Category. Bom, até agora temos nossos DAOs prontos. Vamos criar nossos beans.

Book .java

@Entity
public class Book implements Serializable{
 private static final long serialVersionUID = 888299914160143622L;

 @Id
 @GeneratedValue
 private Long id; 
 private Long isbn; 
 private String title; 
 private String author;
 @ManyToOne
 @JoinColumn(name="category_id")
 @Autowired
 private Category category;
//getters/setters omitidos

Category

@Entity
public class Category implements Serializable {
private static final long serialVersionUID = 6469382724082923338L;
 @Id
 @GeneratedValue
 private Long id; 
 private String categoryName;
 @OneToMany(mappedBy="category",targetEntity=Book.class,fetch=FetchType.LAZY,cascade=CascadeType.ALL)
 @Autowired
 private List<Book> books = new ArrayList<Book>();
//getters/setters omitidos

Nada de especial aqui, apenas um relacionamento @OneToMany/@ManyToOne e o famoso @AutoWired que fará injeção de dependência.

Configurando o Spring

1. Crie um arquivo xml e coloque no package conf. O meu chamei de springconfiguration.xml.

O cabeçalho fica assim para dar suporte aos annotations:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-3.1.xsd">

Agora vamos criar os beans:

<!-- beans -->
 <bean id="category" class="br.com.camilolopes.domain.classes.Category"/>
 <bean id="book" class="br.com.camilolopes.domain.classes.Book"/>
 <bean id="bookstoredao" class="br.com.camilolopes.dao.BookStoreDAO"/>
 <bean id="categorydao" class="br.com.camilolopes.dao.CategoryDAO"/>

No dataSource vou usar o MySql:

<!-- DataSource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
 <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
 <property name="url" value="jdbc:mysql://localhost/test"/>
 <property name="username" value="root"/>
 <property name="password" value="camilo2593"/>
</bean>
 <!-- Using Annotations for mapping -->
 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
 <!-- property for DataBase -->
 <property name="dataSource" ref="dataSource"/>
 <!-- informing the annotated classes -->
 <property name="annotatedClasses">
 <list>
 <value>br.com.camilolopes.domain.classes.Book</value>
 <value>br.com.camilolopes.domain.classes.Category</value>
 </list>
 </property>
 <!-- Property of Hibernate -->
 <property name="hibernateProperties">
 <props>
 <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
 <prop key="hibernate.show_sql">true</prop>
 <prop key="hibernate.hbm2ddl.auto">update</prop>
 </props>
 </property>
 </bean>
<!-- using HibernateTemplate from Spring -->
 <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
 <property name="sessionFactory" ref="sessionFactory"/>
 </bean>

E definindo o uso de annotations para o Spring:

<context:annotation-config/>

E não esqueça de fechar o arquivo com:

</beans>

Agora criaremos uma classe com método main para realizar o CRUD:

bdcrudspring

Esse é o nosso banco, com um cara já persistido:

Crie a classe Main

public class Main {
 public static void main(String[] args) {
// essa classe é o container 
 ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
 "conf/springconfiguration.xml");
 BookStoreDAO bookStoreDAO = (BookStoreDAO) applicationContext.getBean("bookstoredao");
 CategoryDAO categoryDAO = (CategoryDAO) applicationContext.getBean("categorydao");

// Book 
 Book book = new Book();
 book.setAuthor("Camilo Lopes");
 book.setIsbn(1235L);
 book.setTitle("Guia JEE c/ Frameworks");

 //Category 
 Category category = new Category();
 category.getBooks().add(book);
 category.setBooks(category.getBooks());
 category.setCategoryName("Development");
 book.setCategory(category );
// DAO
 categoryDAO.saveOrUpdate(category);
 bookStoreDAO.saveOrUpdate(book);

 findBookById(bookStoreDAO, 1L);
 deleteBook(bookStoreDAO,1L);
 }

 private static void deleteBook(BookStoreDAO bookStoreDAO, long id) {
 Book bookFound = bookStoreDAO.findById(id);
 bookStoreDAO.delete(bookFound);
 System.out.println("Book deleted with sucess " + bookFound.getTitle());

 }
 private static void findBookById(BookStoreDAO bookStoreDAO, Long id){
 Book book = bookStoreDAO.findById(id);
 System.out.println("Title: "+ book.getTitle());
 System.out.println("Author: " + book.getAuthor());
 }
}

O código é bem simples; somente para testarmos. Observe que salvamos um novo livro e em seguida buscamos o mesmo pelo Id e imprimimos usando o console do Java e depois deletamos o livro pelo Id.

Ao rodar, teremos o resultado a seguir:

resultcrudspring

Se formos ao banco, esperamos ter apenas o livro mais recente adicionado com o Id = 2 e o livro com o id = 1 deve estar deletado. Na imagem acima já vimos isso, porque temos o SQL do hibernate habilitado, mas vamos ver na tabela do banco:

resultspringbd

resultcategoryspringbd

GitHub

Acesse o repositório no github com todos os projetos da série Spring: https://github.com/camilolopes/workspacespring.

Bom, vou ficando por aqui… Espero que tenham gostado!

Abraços!