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:
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:
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:
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:
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!