Exemplo CRUD Spring com JDBC Template e Servlet/JSP
Autor: Jabes Felipe | Publicado: 2011-10-16T13:02:00-07:00


Neste post, vamos estudar um dos Frameworks que é líder no mercado em aplicações JEE.

Estou falando do Spring Framework, que foi desenvolvido por Rod Johnson, e é mantido pela empresa&nbsp;

Interface21. Este Framework oferece vários benefícios, possui módulos bem diversificados e pode&nbsp;

ser usado em diversos cenários.

No nosso caso, vamos focar em um dos principais recursos do Spring que é o container de IoC&nbsp;

(Inversion of Control), que também é conhecido como DI (Dependency Injection), a idéia da DI&nbsp;

é de separar uma Interface da classe que a implementa, nos exemplos de DI deste tutorial será&nbsp;

aplicado a injeção através de métodos Setter, mais também pode ser injetado com Construtor.

Através da Injeção de Dependência, facilitará em ligar a camada de persistência de dados&nbsp;

com a camada de negócio e consequentemente com a camada de controller, deixando ambas as camadas&nbsp;

desacopladas entre si.

Além da DI que o Spring ofere, iremos usar o JDBCTemplate para manipular os dados da camada de&nbsp;

persistência, este template possui vários métodos utilitários para trabalhar com JDBC, e o mesmo&nbsp;

já fica encarregado de abrir/fechar conexão, statement e result, apenas vamos precisar de um&nbsp;

Data Source para trabalhar com as querys.

A camada de controller e apresentação, será feita com Servlet/JSP, mostrando assim, como o Spring&nbsp;

é bem modular e que integra facilmente nossas camadas.

Para o exemplo será usado o Eclipse Indigo, TomCat 6,&nbsp;Banco de Dados Derby&nbsp;e o Spring 2.5.6, &nbsp;para baixar o framework,&nbsp;acesse: http://www.springsource.org/download, baixe a versão full, com todos as dependências.
Ao final do post, o projeto está disponível para download, com todas as libs necessárias.


Segue o modelo da estrutura do projeto:




1. Passo: Vamos criar nossa classe modelo, que se chamará Pessoa:
 package model;  
 public class Pessoa {  
      private int id;  
      private String nome;  
      public Pessoa() {  
           super();  
      }  
      public Pessoa(String nome) {  
           super();            
           this.nome = nome;  
      }  
      public int getId() {  
           return id;  
      }  
      public void setId(int id) {  
           this.id = id;  
      }  
      public String getNome() {  
           return nome;  
      }  
      public void setNome(String nome) {  
           this.nome = nome;  
      }  
      @Override  
      public String toString() {  
           return "Pessoa [id=" + id + ", nome=" + nome + "]";  
      }  
 }  



Pessoa.java



2. Passo: Agora vamos criar a Interface DAO.
 package dao;  
 import java.util.List;  
 import model.Pessoa;  
 public interface PessoaDAO {  
      void insert(Pessoa pessoa);  
      List&lt;Pessoa&gt; select();   
      void delete(int id);  
 }  



PessoaDAO.java



3. Passo: Nesta classe, vamos implementar os métodos de contrato da Interface, além disto, teremos um método que será responsável por criar a tabela PESSOA, no banco de dados Derby, (as configurações do banco, data source, etc..., será explicada daqui alguns instantes.). Deve-se ressaltar, que o atributo jdbcTemplate do tipo&nbsp;JdbcTemplate, é responsável por manipular os dados nessa camada de persistência, observe-se que não instanciamos o objeto com new, apenas teremos que ter o método setter deste atributo, para que o container do Spring, posso se encarregar de fazer a injeção de dependência.
 package dao;  
 import java.util.ArrayList;  
 import java.util.List;  
 import java.util.Map;  
 import model.Pessoa;  
 import org.springframework.dao.DataAccessException;  
 import org.springframework.jdbc.core.JdbcTemplate;  
 public class PessoaDAOImp implements PessoaDAO {  
      private JdbcTemplate jdbcTemplate;  
      @SuppressWarnings("unused")  
      private void init() {  
           StringBuilder sb = new StringBuilder();  
           sb.append("CREATE TABLE pessoa (");  
           sb.append("id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (");  
           sb.append("START WITH 1, INCREMENT BY 1),");  
           sb.append(" nome VARCHAR(50),");  
           sb.append(" CONSTRAINT primary_key PRIMARY KEY (id))");  
           try {  
                jdbcTemplate.execute(sb.toString());  
                insert(new Pessoa("Jabes Felipe"));  
           } catch (DataAccessException e) {                 
 //               jdbcTemplate.execute("drop table autor ");  
                e.printStackTrace();  
           }  
      }  
      @Override  
      public void insert(Pessoa pessoa) {  
           jdbcTemplate.update("INSERT INTO pessoa (nome) VALUES (?) ", new Object[]{pessoa.getNome()});  
      }  
      @SuppressWarnings("unchecked")  
      @Override  
      public List&lt;Pessoa&gt; select() {                      
           List&lt;Map&lt;String, Object&gt;&gt; list = jdbcTemplate.queryForList("SELECT id, nome FROM pessoa");  
           List&lt;Pessoa&gt; pessoas = new ArrayList&lt;Pessoa&gt;(list.size());  
           for (Map&lt;String, Object&gt; map : list) {                 
                Pessoa pessoa = new Pessoa();  
                pessoa.setId(Integer.parseInt(map.get("ID").toString()));  
                pessoa.setNome(map.get("NOME").toString());  
                pessoas.add(pessoa);  
           }  
           return pessoas;  
      }  
      @Override  
      public void delete(int id) {  
           jdbcTemplate.update("DELETE FROM pessoa WHERE id=?", new Object[]{id});            
      }  
      public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {  
           this.jdbcTemplate = jdbcTemplate;  
      }       
 }  



PessoaDAOImp.java





4. Passo: Vamos criar a camada de serviço, definimos a Interface.
 package service;  
 import java.util.List;  
 import model.Pessoa;  
 public interface PessoaService {  
      void insert(Pessoa pessoa);  
      List&lt;Pessoa&gt; select();  
      void delete(int id);  
 }  



PessoaService.java





5. Passo: Classe que implementa a Interface de serviço, vale apena ressaltar, que a referência&nbsp;PessoaDAO que um atributo&nbsp;pessoaDAO, será injetado pelo Spring através do método Setter que criamos.


 package service;  
 import java.util.List;  
 import model.Pessoa;  
 import dao.PessoaDAO;  
 public class PessoaServiceImp implements PessoaService {  
      private PessoaDAO pessoaDAO;  
      @Override  
      public void insert(Pessoa pessoa) {  
           pessoaDAO.insert(pessoa);  
      }  
      @Override  
      public List&lt;Pessoa&gt; select() {  
           return pessoaDAO.select();  
      }  
      @Override  
      public void delete(int id) {  
           pessoaDAO.delete(id);            
      }  
      public void setPessoaDAO(PessoaDAO pessoaDAO) {  
           this.pessoaDAO = pessoaDAO;  
      }  
 }  



PessoaServiceImp.java





6. Passo: Já criamos nossa camada de persistência e de serviço, agora vamos criar um Servlet que será nosso controller da camada de tela e serviço.
 package servlets;  
 import java.io.IOException;  
 import javax.servlet.ServletException;  
 import javax.servlet.http.HttpServlet;  
 import javax.servlet.http.HttpServletRequest;  
 import javax.servlet.http.HttpServletResponse;  
 import model.Pessoa;  
 import org.springframework.beans.factory.annotation.Autowired;  
 import org.springframework.web.context.support.SpringBeanAutowiringSupport;  
 import service.PessoaService;  
 import service.PessoaServiceImp;  
 public class PessoaServlet extends HttpServlet {  
      private static final long serialVersionUID = 1L;  
      @Autowired   
      private PessoaService pessoaService;  
      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
           SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);  
           String acao = request.getParameter("acao");  
           if ("salvar".equals(acao)) {  
                Pessoa pessoa = new Pessoa();  
                pessoa.setNome(request.getParameter("nome"));  
                pessoaService.insert(pessoa);  
           } else if ("excluir".equals(acao)) {  
                int id = Integer.parseInt(request.getParameter("id"));  
                pessoaService.delete(id);  
           }  
           request.setAttribute("pessoas", pessoaService.select());  
           getServletConfig().getServletContext().getRequestDispatcher("/home.jsp").forward(request,response);  
      }  
      public void setAutorService(PessoaServiceImp pessoaService) {  
           this.pessoaService = pessoaService;  
      }  
 }  



PessoaServlet.java



7. Passo: Agora vamos configurar as definições necessárias do Spring no arquivo web.xml.
 &lt;?xml version="1.0" encoding="UTF-8"?&gt;  
 &lt;web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"&gt;  
  &lt;display-name&gt;Spring&lt;/display-name&gt;  
  &lt;welcome-file-list&gt;    
   &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;    
  &lt;/welcome-file-list&gt;  
  &lt;!-- Define os arquivos de configuracoes XML para o contexto Spring --&gt;  
  &lt;context-param&gt;  
   &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;  
   &lt;param-value&gt;/WEB-INF/applicationContext.xml&lt;/param-value&gt;  
  &lt;/context-param&gt;  
  &lt;!-- Inicializa o Spring Web Application Context --&gt;  
  &lt;listener&gt;  
   &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;  
  &lt;/listener&gt;  
  &lt;!-- Ativa os escopos web para os beans no Spring --&gt;  
  &lt;listener&gt;  
   &lt;listener-class&gt;org.springframework.web.context.request.RequestContextListener&lt;/listener-class&gt;  
  &lt;/listener&gt;  
  &lt;servlet&gt;  
   &lt;description&gt;&lt;/description&gt;  
   &lt;display-name&gt;PessoaServlet&lt;/display-name&gt;  
   &lt;servlet-name&gt;PessoaServlet&lt;/servlet-name&gt;  
   &lt;servlet-class&gt;servlets.PessoaServlet&lt;/servlet-class&gt;  
  &lt;/servlet&gt;  
  &lt;servlet-mapping&gt;  
   &lt;servlet-name&gt;PessoaServlet&lt;/servlet-name&gt;  
   &lt;url-pattern&gt;/PessoaServlet&lt;/url-pattern&gt;  
  &lt;/servlet-mapping&gt;  
 &lt;/web-app&gt;  



web.xml



8. Passo: Agora chegou, a parte mais importante, que é o arquivo de configuração dos beans, contexto e datasource do Spring. Neste arquivo está configurado o Data Source que contém as informações do banco, o jdbcTemplate que contém uma referência ao dataSource, também configuramos os properties do banco e por fim, temos a definição de pessoaDAO e pessoaService.
 &lt;?xml version="1.0" encoding="UTF-8"?&gt;  
 &lt;!--  
  - Application context definition for JPetStore's business layer.  
  - Contains bean references to the transaction manager and to the DAOs in  
  - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").  
  --&gt;  
 &lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
           xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"  
           xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee"  
           xmlns:tx="http://www.springframework.org/schema/tx"  
           xsi:schemaLocation="  
                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
                http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd  
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"&gt;  
      &lt;bean id="pessoaService" class="service.PessoaServiceImp" lazy-init="false" scope="singleton"&gt;  
           &lt;property name="pessoaDAO" ref="pessoaDAO" /&gt;  
      &lt;/bean&gt;  
      &lt;bean id="pessoaDAO" class="dao.PessoaDAOImp" init-method="init" lazy-init="false" scope="singleton"&gt;  
           &lt;property name="jdbcTemplate" ref="jdbcTemplate" /&gt;  
      &lt;/bean&gt;  
      &lt;!-- arquivo properties --&gt;  
      &lt;context:property-placeholder location="classpath:resources/jdbc.properties" /&gt;  
      &lt;!-- Config. datasource --&gt;  
      &lt;bean id="dataSource"   
            class="org.apache.commons.dbcp.BasicDataSource"   
            destroy-method="close"  
            p:driverClassName="${jdbc.driverClassName}"   
            p:url="${jdbc.url}"   
            p:username="${jdbc.username}"  
            p:password="${jdbc.password}" /&gt;  
      &lt;!-- Transaction manager for a single JDBC DataSource (alternative to JTA) --&gt;  
      &lt;bean id="transactionManager"   
         class="org.springframework.jdbc.datasource.DataSourceTransactionManager"  
            p:dataSource-ref="dataSource"/&gt;  
      &lt;!-- JDBC template --&gt;  
      &lt;bean  
           id="jdbcTemplate"  
           class="org.springframework.jdbc.core.JdbcTemplate"  
           lazy-init="false"&gt;  
                &lt;property name="dataSource" ref="dataSource" /&gt;  
                &lt;property name="lazyInit" value="false" /&gt;  
      &lt;/bean&gt;  
 &lt;/beans&gt;  



applicationContext.xml





9. Passo: Segue informações do banco de dados Derby, que estão contidas em um arquivo de properties.
 # Properties file with JDBC settings.  
 #  
 # Applied by &lt;context:property-placeholder location="jdbc.properties"/&gt; from  
 # various application context XML files (e.g., "applicationContext-*.xml").  
 # Targeted at system administrators, to avoid touching the context XML files.  
 #-------------------------------------------------------------------------------  
 jdbc.driverClassName=org.apache.derby.jdbc.EmbeddedDriver  
 jdbc.hostname=localhost  
 jdbc.database=spring  
 jdbc.username=spring  
 jdbc.password=spring  
 jdbc.port=3306  
 jdbc.url=jdbc\:derby\:directory\:${jdbc.database}ExemploDB;create\=true  





10. Passo: Segue as telas jsp.
 &lt;% response.sendRedirect("./PessoaServlet"); %&gt;  



index.jsp


 &lt;%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%&gt;  
 &lt;%@ page language="java" contentType="text/html; charset=ISO-8859-1"  
      pageEncoding="ISO-8859-1"%&gt;  
 &lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;  
 &lt;html&gt;  
 &lt;head&gt;  
 &lt;meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"&gt;  
 &lt;title&gt;SPRING&lt;/title&gt;  
 &lt;script type="text/javascript"&gt;  
 function validar() {  
      var nome = document.getElementById("nome");  
      if (nome == null || nome.value == '') {  
           alert("Nome obrigatorio!");   
           return false;            
      } else {            
            return true;  
      }  
 }  
 &lt;/script&gt;  
 &lt;/head&gt;  
 &lt;body&gt;  
      &lt;form action="./PessoaServlet" method="get" onsubmit="return validar();"&gt;  
           &lt;table&gt;  
                &lt;tr&gt;  
                     &lt;td&gt;Nome:&lt;/td&gt;  
                     &lt;td&gt;&lt;input id="nome" name="nome" type="text"&gt;&lt;/td&gt;  
                &lt;/tr&gt;  
                &lt;tr&gt;  
                     &lt;td colspan="2"&gt;&lt;input name="acao" type="hidden" value="salvar" /&gt;  
                          &lt;input type="submit" value="salvar" /&gt;  
                     &lt;/td&gt;  
                &lt;/tr&gt;  
           &lt;/table&gt;  
           &lt;br /&gt;  
           &lt;table&gt;  
                &lt;tr&gt;  
                     &lt;td&gt;ID&lt;/td&gt;  
                     &lt;td&gt;Nome&lt;/td&gt;  
                     &lt;td&gt;Excluir&lt;/td&gt;  
                &lt;/tr&gt;  
                &lt;c:forEach var="pessoa" items="${pessoas}"&gt;  
                     &lt;tr&gt;  
                          &lt;td&gt;&lt;c:out value="${pessoa.id}" /&gt;&lt;/td&gt;  
                          &lt;td&gt;&lt;c:out value="${pessoa.nome}" /&gt;&lt;/td&gt;  
                          &lt;td&gt;&lt;a href="./PessoaServlet?acao=excluir&amp;id=${pessoa.id}"&gt;Excluir&lt;/a&gt;  
                          &lt;/td&gt;  
                     &lt;/tr&gt;  
                &lt;/c:forEach&gt;  
           &lt;/table&gt;  
      &lt;/form&gt;  
 &lt;/body&gt;  
 &lt;/html&gt;  



home.jsp



Exemplo da tela:








Para quem quiser baixar o projeto desenvolvido,&nbsp;clique aqui.
Qualquer dúvida, crítica ou sugestão, fico à disposição.