Como acessar o BD com Struts

15 respostas
cu_ringa

Eu estou com a seguinte dúvida. Coloco o acesso ao banco de dados num Servlet ou numa Action? Agora num servlet num tem como eu retornar um ActionForward para apontar p\ minha jsp p\ poder fomatar, ja na Action nao tem como colocar o objeto Connection na inicialização como no metodo init do servlet, p nao ter q ter que abrir uma conexao toda vez que chamar essa servlet??? Como posso prosseguir n adcionando mais camadas, já q o sistema e simples???

Se eu fizer uma Action que instancia uma classe de conexao (classe normal) com o banco, eu to deixando de usar a regra do Struts de q todas as chamadas tem q passar pelo ActionServlet??? Mas mesmo assim to fazendo uma conexao toda vez que solicito a pagina e o que quero e deixar a mesma conexao para varias requisições.

15 Respostas

luiz_ross
Pergunta: vc esta usando um servlet acessando uma action ou uma action acessando um servlet? Por que se for, ja começou tudo errado
Rafael_Nunes

Você pode criar uma classe que faça a conexão com o DB, e toda classe de persistência extender ela.

Eu por exemplo numa app que tenho aqui fiz assim:
package br.com.in9.dao;

import java.sql.*;
import javax.sql.DataSource;
import javax.naming.Context;
import javax.naming.InitialContext;

/**
 * Classe responsável por retornar o Objeto DataSource, com uma conexão do pool.
 * Toda classe que necessitar de alguma trasanção com o banco de dados, deverá herdar
 * esta classe, herdando-a, já terá como atributos o objeto de conexão, o Statement
 * para execução de <i>querys</i>, um objeto result set com o resultado da <i>query</i>
 * e uma StringBuffer para armazenamento da <i>query</i>
 * @author Rafael Nunes - <a href="mailto:[email removido]">[email removido]</a>
 * @version 1.0 - 24/01/2004
 */

public class BancoDados {
	/**Objeto StringBuffer para armazenamento da <i>query</i>*/
    protected StringBuffer sql;

    /**Objeto Statement para execução da <i>query</i>*/
    protected Statement stmt;

    /**Objeto Connection que retorna uma conexão do pool*/
    protected Connection connection;

    /**Objeto ResultSet que armazena o resultado da <i>query</i>*/
    protected ResultSet rs;

    /**
     * Construtor da classe, sem argumentos
     *
     */
    public BancoDados() {
    }


    /**
     * Método responsável por retornar uma conexão do Pool
     * @return Connection
     * @throws SQLException
     */
    protected Connection getConnection() throws SQLException {

       try{

   //		Obtém o namming context
	    Context initCtx = new InitialContext();
	    Context envCtx = (Context) initCtx.lookup("java:comp/env");

   //		Recupera o objeto Datasource
	    DataSource ds = (DataSource) envCtx.lookup("jdbc/dbin9");

   //		Aloca uma conexão no Pool
	    connection = ds.getConnection();

       }catch(Exception e){
         	e.printStackTrace();
       }

	   return connection;

    }

}

E todas minhas classes DAO herdam BancoDados.

jgbt

acho que vc esta confundido um pouco as camadas da sua aplicação e a responsabilidade e cada uma.
vc não precisa abrir conexões sempre que vai ao bd, crie um datasource p/ isso, ou implemente vc mesmo um pool de conexões.
suas actions podem/devem chamar classes de negocio, ou acesso bd(se sua app for pequena.)
de acordo com o resultado dessas classe vc encaminha seu forward.
basicamente seria assim, mas da p/ fazer ce outras maneiras mais elegantes.

[]'s

danieldestro

Simplesmente faça assim:

//seus imports 

public class SeuAction extends Action {
  public ActionForward execute( ... ) {
    Connection conn = getConecctionDeAlgumLugar();
    //usar a conexão
  }
}

Aí, quando você for aprendendo melhor sobre separação de camadas, separação de responsabilidades e padrões de projeto, você vai melhorando.

cu_ringa

O problema q to encontrando em colocar o acesso ao banco em outra classe q nao seja Action e chamar essa classe de uma Action e q se der erro nessa classe ai o struts nao acusa e fica como se o cadastro tivesse sido realizado com sucesso. Eu acho q o struts so acusa erro p ir pra aquela tag input q e uma classe Action

danieldestro

Oras, faça a sua classe responsável pela conexão lançar uma exceção caso ocorra algum problema na obtenção da conexao e trate isso no Struts, via configuração de tratamento de exceções. Simples!

fmeyer

us em ejb …
:slight_smile:

caiofilipini

Peraí, usar EJB pra fazer uma simples conexão com o banco de dados (assumindo que seja realmente algo simples) é, como dizem, “matar mosca com canhão”. Se o cara nunca teve contato com EJB antes, ele vai demorar muito mais pra aprender a usá-los (e corrigir erros de deploy) do que pra conseguir conectar ao banco usando a dica do Daniel Destro, por exemplo. :?

[]'s

cu_ringa

o proplema q to tendo e q quero armazenar o ResultSet que agora transformei numa Collection e passar para uma jsp(via req.setAtribute(e os argumentos)) ou para um Servlet Context, n to conseguindo justamente faer isso q o Conteiner fecha

danieldestro

NUNCA passe seu ResultSet para o JSP. Jogue os dados em algum tipo de estrutura (ex: Uma Collection de JavaBeans). e mande estes dados pro JSP e feche o ResultSet.

caiofilipini

E o Statement! E a Conexão! :lol:

[]'s

cu_ringa

O problema ainda continua

to acessando o banco atraves de uma classe q fiz, essa chamada de uma LookupDispatchAction, nessa mesma classe pego o resultado do banco q e uma ResultSet e passo para uma Collection onde a colecao e armazenada no bean EmpresaCollection. No final dessas operacoes a LookupDispatchAction retorna um ActionForward para q a jsp seja chamada para mostrar o resultado do banco. O problema esta justamente ai, nao to conseguindo mostrar o resultado e o servidor( tomcat ) ta fechando sozinho q chamo a jsp. Como devo prosseguir p mostrar o resultado na JSP???

Codigo da classe EmpresaCollection

import java.util.*;

public class EmpresaCollection {
	
	/**
	 * Method EmpresaCollection
	 *
	 *
	 */
	
	private Collection collection; 
	 
	public EmpresaCollection(){}
	
	public void setCollection(Collection collection){
		
		this.collection = collection;
	}
	
	public Collection getCollection(){
		
		return collection;
	}
		
}

parte do Codigo da classe CadastrarLookupDispacthAction

public ActionForward cadastrar(ActionMapping map, ActionForm form, HttpServletRequest req,
																 HttpServletResponse res) throws IOException, ServletException{
						
		CadastrarEmpresaForm cef = (CadastrarEmpresaForm) form; 
		
		CadastrarEmpresaBanco ceb = new CadastrarEmpresaBanco();
		ceb.insert(cef.getCnpj(), cef.getRazaosocial(), cef.getNomefantasia(), cef.getRua(), cef.getNumero(), cef.getBairro(), cef.getCidade(), cef.getUf());
		EmpresaCollection emp = new EmpresaCollection();
		emp.setCollection(ceb.select()); 
																								 	
		return map.findForward("sucesso");
		
	}

Codigo da classe CadastrarEmpresaBanco

package app;

import java.util.*;
import java.sql.*;
import java.io.*;
import javax.servlet.*;

public class CadastrarEmpresaBanco {
	
	/**
	 * Method CadastrarEmpresaBanco
	 *
	 *
	 */
	 
	private Connection con = null;
	private ResultSet rs = null;
	private Properties props = null;
		
	public CadastrarEmpresaBanco() {
		// TODO: Add your code here
						
		getProperties();
		getConnection();
	}	
	
	private void getProperties(){
		
		SQLProperties sqlp = SQLProperties.getInstance();
		props = sqlp.getSQLProperties();		
	}
			
	private void getConnection(){
	
		try{
			
			Class.forName(props.getProperty("connection.driver"));
			con = DriverManager.getConnection(props.getProperty("connection.url"));
			
		}
		catch(ClassNotFoundException cnfe){
			System.out.println("marujo");			
		}
		catch(SQLException sqle){
			System.out.println("marujo2");
			//erro na conexao
		}		
		
	}
	
	public void insert(String cnpj, String razao_social, String nome_fantasia, String rua, String num, String bairro, String cidade, String uf){
				
		try{
		
			Statement stmt = con.createStatement();
			rs = stmt.executeQuery(props.getProperty("insert.select.empresa"));
			
			double cod_empresa = 1;
											
			if(rs.next())
				cod_empresa += Double.parseDouble(rs.getString(1));
																				
			PreparedStatement pstmt = con.prepareStatement(props.getProperty("insert.empresa"));
			pstmt.clearParameters();
			pstmt.setDouble(1, cod_empresa);
			pstmt.setString(2, cnpj);
			pstmt.setString(3, razao_social);
			pstmt.setString(4, nome_fantasia);
			pstmt.setString(5, rua);
			pstmt.setString(6, num);
			pstmt.setString(7, bairro);
			pstmt.setString(8, cidade);
			pstmt.setString(9, uf);
			pstmt.executeUpdate();
						
		}
		catch(SQLException sqle){
			System.out.println("marujo3");
			sqle.printStackTrace();
			//erro de conexao
		}		
		finally{
			
			try{
								
				rs.close();
				con.close();				
			}
			catch(SQLException se){}		
		}
		
	}
	
	protected Collection select(){
		
		try{
		
			Statement stmt = con.createStatement();
			rs = stmt.executeQuery(props.getProperty("select.empresa"));													
			Collection c = (Collection) rs;			
			return c;
		}
		catch(SQLException sqle){
			System.out.println("marujo4");
			sqle.printStackTrace();
			//erro de conexao
		}		
		
		return (Collection) rs;	
	}
	
}

Código da jsp

&lt;%@ page isELIgnored="false" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %&gt;

&lt;html&gt;
&lt;body&gt;
&lt;table&gt;
	&lt;c:forEach var="row" items="EmpresaCollection.collection"&gt;
		&lt;c:out value="${row.cnpj}" /&gt;
	&lt;/c:forEach&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
danieldestro

Algumas considerações.

Sua classe EmpresaCollection não tem muito sentido. Você poderia usar uma Collection diretamente, não acha?

E mesmo assim, depois que você pega os dados e joga na sua collection, você não coloca esses dados disponíveis para o JSP, como por exemplo no request.

Outra coisa, o que significa isso Collection c = (Collection) rs; ???
Impossível!

É melhor você fazer algo assim:

Empresa.java

public class Empresa { private int id; private String nome; //métodos get e set }

No seu Action:

Collection c = empresaDAO.select(); request.setAttribute("empresas",c); //faz forward pro seu JSP

EmpresaDAO.java:

public Collection select() { Collection c = new ArrayList(); //faz o select no BD while( rs.next() ) { Empresa e = new Empresa(); e.setId( rs.getInt("id") ); e.setNome( rs.getString("nome") ); c.add( e ); } return c; }

cu_ringa

ei daniel fiz o q vc falou, mas n sei o q esta acontecendo q qnd clico no botao cadastrar o tomca ta fechando, vo postar as classes

Codigo da LookupDispatchAction
public ActionForward cadastrar(ActionMapping map, ActionForm form, HttpServletRequest req,
																 HttpServletResponse res) throws IOException, ServletException{
						
		CadastrarEmpresaForm cef = (CadastrarEmpresaForm) form; 
		
		CadastrarEmpresaBanco ceb = new CadastrarEmpresaBanco();
		ceb.insert(cef.getCnpj(), cef.getRazaosocial(), cef.getNomefantasia(), cef.getRua(), cef.getNumero(), cef.getBairro(), cef.getCidade(), cef.getUf());
		Collection c = ceb.select();
		req.setAttribute("empresa", c);
																												 	
		return map.findForward("sucesso");
		
	}
CadastrarEmpresaBanco
protected Collection select(){
		
		Collection c = null;
		
		try{
		
			Statement stmt = con.createStatement();
			rs = stmt.executeQuery(props.getProperty("select.empresa"));													
			c = new ArrayList();
			   
   	//faz o select no BD
   		while( rs.next() ) {
     		EmpresaBean eb = new EmpresaBean();
     		eb.setCnpj(rs.getString("cnpj"));
     		eb.setRazaosocial(rs.getString("razaosocial"));
     		eb.setNomefantasia(rs.getString("nomefantasia"));
     		eb.setRua(rs.getString("rua"));
     		eb.setNumero(rs.getString("numero"));
     		eb.setBairro(rs.getString("bairro"));
     		eb.setCidade(rs.getString("cidade"));
     		eb.setUf(rs.getString("uf"));
     		c.add(eb);
    }
   		stmt.close();
   		
   		return c;
		}
		catch(SQLException sqle){
			System.out.println("marujo4");
			sqle.printStackTrace();
			//erro de conexao
		}
		finally{
			
			try{
				rs.close();
				con.close();
			}
			catch(SQLException sqle){
			System.out.println("marujo4");
			sqle.printStackTrace();
			//erro de conexao
			}			
		
		}				
	
		return c;	
	}
jsp
&lt;%@ page isELIgnored="false" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %&gt;

&lt;html&gt;
&lt;body&gt;
&lt;table&gt;

	&lt;c:forEach var="linha" items="${empresa}"&gt;<br />
		&lt;c:out value="${linha.cnpj}" /&gt;<br />
		&lt;c:out value="${linha.razaosocial}" /&gt;<br />
		&lt;c:out value="${linha.nomefantasia}" /&gt;<br />
		&lt;c:out value="${linha.numero}" /&gt;<br />
		&lt;c:out value="${linha.rua}" /&gt;<br />
		&lt;c:out value="${linha.bairro}" /&gt;<br />
		&lt;c:out value="${linha.cidade}" /&gt;<br />
		&lt;c:out value="${linha.uf}" /&gt;<br />
	&lt;/c:forEach&gt;
	
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
EmpresaBean
package app;

public class EmpresaBean {
	
	/**
	 * Method EmpresaBean
	 *
	 *
	 */

	private String cnpj;
	private String razao_social;
	private String nome_fantasia;
	private String rua;
	private String numero;
	private String bairro;
	private String cidade;
	private String uf;
	
	public EmpresaBean() {
		// TODO: Add your code here
	}
	
	public void setCnpj(String cnpj){
		
		this.cnpj = cnpj;
	}
	
	public String getCnpj(){
		
		return cnpj; 
	}
	
	public void setRazaosocial(String razao_social){
		
		this.razao_social = razao_social;
	}
	
	public String getRazaosocial(){
		
		return razao_social;
	}
	
	public void setNomefantasia(String nome_fantasia){
		
		this.nome_fantasia = nome_fantasia;
	}
	
	public String getNomefantasia(){
		
		return nome_fantasia;
	}
	
	public void setRua(String rua){
		
		this.rua = rua;
	}
	
	public String getRua(){
		
		return rua;
	}
	
	public void setNumero(String numero){
		
		this.numero = numero;
	}
	
	public String getNumero(){
		
		return numero;
	}
	
	public void setBairro(String bairro){
		
		this.bairro = bairro;
	}
	
	public String getBairro(){
		
		return bairro;
	}
	
	public void setCidade(String cidade){
		
		this.cidade = cidade;
	}
	
	public String getCidade(){
		
		return cidade;
	}
	
	public void setUf(String uf){
		
		this.uf = uf;
	}
	
	public String getUf(){
		
		return uf;
	}
	
}

struts-config.xml
<action path="/cadastrar-empresa" forward="/jsp/cad_empresa.jsp" /> <action path="/cadastrar_empresa" type="app.CadastrarLookupDispacthAction" name="cadastrarEmpresaForm" scope="request" validate="true" input="/cadastrar-empresa.do" parameter="method"> <forward name="sucesso" path="/jsp/tbl_empresa.jsp" /> </action> [code]
danieldestro

O Tomcat está fechando o que?
Se for a conexão, não se prestou atenção, mas a conexão é fachada no método select, percebeu?

Criado 11 de março de 2005
Ultima resposta 14 de mar. de 2005
Respostas 15
Participantes 7