Qual framework de persintência utilizar?

46 respostas
L

boa tarde,

Estou com o seguinte problema, trabalho hoje com o Delphi 5 + Oracle estamos começando a migração para o Java + Web
as regras de negócios estão todas no banco de dados são Triggers, Procedures, Functions, etc.

Nesse meu cenário onde eu tenho tudo gerado pelo banco de dados qual o melhor framework de persinstência ?

Atenciosamente…

Luciano Antunes

46 Respostas

joaosouza

Olá…



:smiley:

L

não entendi ?

o spring para a camada de persistencia.

Rodrigo.Lima

JPA.

Recomendo Wicket + EJB3

recoma

JPA/Hibernate…

Existem várias ferramentas para gerar as classes Java a partir das tabelas do Oracle (Netbeans é uma boa ferramenta, só precisa adicionar o Hibernate, pois o padrão é o Toplink).

rodrigoallemand

joaosouza:
Olá…



:smiley:

Viajou!

Sugiro, já que seu entendimento é inicial, partir pro hibernate mesmo, sem anotação pra ralar um pouco nos mapeamentos pra poder entender o funcionamento. Se o caso for corporativo mesmo, tipo sistemas de empresa, partir pro JPA!
E entre HibernateEntityManager (JBoss RedHat) e Toplinks (Oracle), sinta-se a vontade pra escolher!

Rodrigo.Lima

Na verdade, não importa se vc escolher entre toplink ou hibernate no começo, pois JPA funciona “sobre” eles.

L

Use a JPA (é só uma interface sobre qualquer framework de persistência), mas dê preferência ao Hibernate, pois as mensagens de erros e os log de erro são mais legíveis no Hibernate do que no Toplink Essentials.

L

obrigado pessoal pelas respostas,

notei que o hibernate pelo menos para o inicio e a melhor opção já venho estudando ele a uma bom tempo
meu unico medo quanto ao seu uso e referente aquilo que eu havia falado as minhas regras de negocio ficam dentro do banco de dados
um exemplo so para esclarecer eu tenho triggers que geram as chaves primarias para mim, o hibernate consegue se entender com isso.

L

Cara,

pra esse seu caso aí eu usaria só JDBC. Acho que vc vai evitar boas dores de cabeça fazendo isso. Use no máximo o JDBCTemplate do Spring pra te ajudar…

Hibernate e JPA acho que pro seu caso não agregam muito, pois, pelo que eu entendi, vcs querem continuar a deixar as regras todas no banco, o que não é uma boa prática com Java…mas…

[]'s

F

Hibernate mais maduro e todos ja sabem como funciona o EJB é bom mas ainda é novidade pouco suporte !

Att

R
  • Pense 10x se jdbc simples não atende bem ao seu problema.
  • Se não for usar EJB´s, pense em utilizar o Spring DAO support, é bem simples.
  • Se for utilizar ejb3, estude a possibilidade de usar JPA/Hibrnate.

[]´s

L

até concordo que deveria utilizar o jdbc puro, mas o hibernate me traz uma forma melhor de lidar com os objetos a serem persistidos sem contar com as consultas que sao possiveis fazer com ele.

usar o hibernate no meu caso seria ruim mesmo assim ?

R

Não é que seja ruim, o que eu aconselho é você avaliar se vale a pena incluir qualquer tipo de complexidade num projeto, e não sair utilizando frameworks pq está na moda.

Mas se houver um margem para aprendizado, sim, vale a pena utilizar o hibernate, é uma ferramenta bem interessante.

[]'s

L

quanto a margem para o aprendizado não há problema conheco o hibernate já faz um bom tempo venho lendo a sua documentacao vendo exemplos de utilizacao entre outras coisas no modo XML sem anotacoes, mas o que me deixa preocupado e se ele vai me dar a liberdade de manter as minhas regras de negocio no banco de dados.

agodinho

Visto que vc está migrando acho que hibernate não é o melhor caminho.

O hibernate assume que seu modelo de dados foi desenhado para atender um modelo OO.

O hibernate favorece o desenvolvimento de aplicações oo. Se vc tem muita trigger e regra de negócios no banco é mais provável que sua aplicação seja orientada à banco (por mais que o código seja OO). Isso pode se tornar uma grande dor de cabeça visto que é bem possível que vc tenha de alterar algo no seu modelo de dados para melhor utilizar o hibernate e isso nem sempre é possível. Assumindo que vc não vai alterar seu modelo por causa de alguma necessidade do hibernate vc acabará tendo de utilizar algum recurso “extra” do hibernate pra dar a volta em alguma de suas limitações e isso acaba sempre complicando a manutenção.

Dentro do processo de migração você terá de aprender a utlizar todas as ferramentas (frameworks e bibliotecas) que eleger pro seu arsenal. Sugiro então que vc fique com o simples (que já foi validado pelo mercado), feijão com arroz, pra evitar ondas e modismos que possam aumentar seu risco.

Pra aplicações com essa configuração (orientada à banco) eu sugiro o iBatis/sqlMap.

IMO (e na prática).

Woody

L

com o ibatis você acha que o meus problemas serão resolvidos deixando toda a regra de negocio no banco de dados ?

ddduran

Se a regra de negocio está em procs, triggers, etc. Aconselho usar JDBC logo

L

o iBatis seria a solução então ?

ddduran

não, não seria tão ruim uma coisa legal do hibernate é que ele lhe permite sempre que for preciso passar por cima do framework.
Apenas analise seu sistema melhor para não acabar usando hibernate (ou qualquer outro framework) só por usar

agodinho

polui muito.

O iBatis ajuda exatamente nisso. Todos seus sqls ficarão em arquivos XMLs simples. Vc ainda terá uma camada de persistência (DAO) mas sua camada não fala jdbc. Ela simplismente delega isso pro ibatis.

agodinho

Cara, para a configuração de aplicação que foi mencionada (uma aplicação orientada à banco), seira uma das possíveis soluções sim. Se é a melhor depende de muitos outros detalhes. Só pra dar um exemplo: é possível que sua equipe torça o nariz e nem tente aprender a usar a ferramenta e, por melhor que seja, pode acabar afundando seu projeto.

Eu sugiro iBatis pq é um dos mais utilizados mas existem outros. Não aconselho o hibernate pra esse caso pq seu banco foi modelado sem levar em consideração qq necessidade desse framework.

Já cansei de ver gente reclamando do hibernate simplesmente por telo adotado em situações onde ele não é recomendado:

  • Se vc tem baixo controle do modelo de dados (o modelo é legado, possui regras rígidas de alteração ou limitação da utilização de recursos do banco)
  • O hibernate gera querys (DDL, MDL, sei lá) dinâmicamente - por essas serem geradas dinâmicamente não são passíveis de tunning (algumas empresas grandes proíbem o hibernate por isso).

O hibernate é ótimo - não me entenda mal. Só não é recomendado para seu caso.

agodinho

ddduran:
não, não seria tão ruim uma coisa legal do hibernate é que ele lhe permite sempre que for preciso passar por cima do framework.
Apenas analise seu sistema melhor para não acabar usando hibernate (ou qualquer outro framework) só por usar

Desculpe, não concordo. IMO.
JDBC puro só pra coisas muito simples (não comerciais) …
Então acho que no caso de persistência, só por usar, ainda vale.

veja:
http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=78&t=000939

Woody

agodinho

Toda regra de negócios no banco já não é uma boa solução pra todos os casos, então: não irá resolver todos seus problemas mas não vai te limitar na implementação da solução.

L

quanto ao aprendizado da equipe nao vejo problemas somos apenas dois, mas de inicio sou eu quem vai dar o pontape inicial estou mesmo tirando o maior número de duvidas possiveis para nao me arrepender depois, por exemplo eu pretendo trabalhar com as seguintes ferramentas Struts2 + Spring + iBatis que conforme estou vendo e a melhor solucao para mim.

estava lendo o manual do iBatis existe alguma forma de eu usar o Insert Into Teste(descricao) Values (‘xxxx’) Returning Id e uma construcao na qual eu posso utilizar no oracle, ou eu tenho que utilizar o selectKey que ele demonstra do manual ?

Desde já agradeço a todos pelas opiniões…

Atenciosamente …

Luciano Antunes

agodinho

Só a título de exemplo:

Arquivo projeto.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE sqlMap PUBLIC 
"-//ibatis.apache.org//DTD SQL Map 2.0//EN" 
"http://ibatis.apache.org/dtd/sql-map-2.dtd">

<!-- 
Author: Anaximandro de Godinho.
Versão: $Revision: 1.20 $
-->

<sqlMap namespace="Projeto">

	<!-- Alias do "Transfer Object" da entidade "Projeto Base" utilizado nos resultados. -->
	<typeAlias alias="ProjetoTO" type="br.com.cvrd.igrm.to.ProjetoTO" />

	<!-- Mapeamento do "Transfer Object" da entidade "Projeto". -->
	<resultMap id="ProjetoResult" class="ProjetoTO">
		<result property="idProjeto"		column="FVGIDPRO" />
		<result property="idModelo"			column="FVGIDMOD" />
		<result property="idProjetoPai"		column="FVGIDPRF" />
		<result property="nome"				column="FVGNMPRO" />
		<result property="idAlternativo"	column="FVGALPRO" />
		<result property="contexto"			column="FVGCXPRO" />
	</resultMap>

	<sql id="_selectProjeto">
		SELECT	FVGIDPRO,
				FVGIDMOD,
				FVGIDPRF,
				FVGNMPRO,
				FVGALPRO,
				${DBALIAS}.IGRM.obterContextoCorporativo( FVGNMPRO, FVGIDPRF, FVGIDMOD ) as FVGCXPRO
		FROM	${DBALIAS}.FVGPROJT
	</sql>

	<sql id="_orderByNomeProjeto">
		ORDER
		BY		FVGNMPRO
	</sql>

	<select id="obter_Projetos" resultSetType="FORWARD_ONLY" fetchSize="50" resultMap="ProjetoResult">
		<include refid="_selectProjeto" />
		<include refid="_orderByNomeProjeto" />
	</select>

	<select id="obter_Projeto" resultSetType="FORWARD_ONLY" fetchSize="1" resultMap="ProjetoResult" parameterClass="Integer">
		<include refid="_selectProjeto" />
		WHERE	FVGIDPRO = #idProjeto#
	</select>
	
	<select id="obter_ProjetoPorIdAlternativo" resultSetType="FORWARD_ONLY" fetchSize="1" resultMap="ProjetoResult" parameterClass="String">
		<include refid="_selectProjeto" />
		WHERE	FVGALPRO = #idAlternativo#
	</select>

	<select id="obter_ProjetoPorNome" resultSetType="FORWARD_ONLY" fetchSize="1" resultMap="ProjetoResult" parameterClass="String">
		<include refid="_selectProjeto" />
		WHERE	FVGNMPRO = #nomeProjeto#
	</select>
	
	<select id="contar_ProjetosRaiz" resultSetType="FORWARD_ONLY" fetchSize="1" resultClass="Integer">
		SELECT	Count( 1 ) AS Quantidade
		FROM	${DBALIAS}.FVGPROJT
		WHERE	FVGIDPRF IS NULL
	</select>

	<select id="obter_ProjetosRaiz" resultSetType="FORWARD_ONLY" fetchSize="50" resultMap="ProjetoResult">
		<include refid="_selectProjeto" />
		WHERE	FVGIDPRF IS NULL
		<include refid="_orderByNomeProjeto" />
	</select>

	<select id="contar_ProjetosPorProjetoPai" resultSetType="FORWARD_ONLY" fetchSize="1" resultClass="Integer" parameterClass="Integer">
		SELECT	COUNT( FVGIDPRO )
		FROM 	${DBALIAS}.FVGPROJT
		WHERE 	FVGIDPRF = #idProjetoPai#
	</select>
	
	<select id="obter_ProjetosPorProjetoPai" resultSetType="FORWARD_ONLY" fetchSize="50" resultMap="ProjetoResult" parameterClass="Integer">
		<include refid="_selectProjeto" />
		WHERE	FVGIDPRF = #idProjetoPai#
		<include refid="_orderByNomeProjeto" />
	</select>

	<insert id="incluir_Projeto" parameterClass="ProjetoTO">
		<selectKey type="pre" resultClass="Integer" keyProperty="idProjeto">
			SELECT ${DBALIAS}.FVGPROJT_S01.NextVal AS ID FROM DUAL
		</selectKey>
		INSERT 
		INTO	${DBALIAS}.FVGPROJT(
				FVGIDPRO,
				FVGIDMOD,
				FVGIDPRF,
				FVGNMPRO,
				FVGALPRO
		) VALUES (
				#idProjeto#,
				#idModelo#,
				#idProjetoPai#,
				#nome#,
				#idAlternativo#
		)
	</insert>

	<update id="alterar_Projeto" parameterClass="ProjetoTO">
		UPDATE	${DBALIAS}.FVGPROJT
		SET		FVGIDMOD = #idModelo#,
				FVGIDPRF = #idProjetoPai#,
				FVGALPRO = #idAlternativo#,
				FVGNMPRO = #nome#
		WHERE	FVGIDPRO = #idProjeto#
	</update>

	<delete id="excluir_Projeto" parameterClass="Integer">
		DELETE
		FROM	${DBALIAS}.FVGPROJT
		WHERE	FVGIDPRO = #idProjeto#
	</delete>

<!-- especificos -->

	<select id="contar_ProjetosPorModelo" resultSetType="FORWARD_ONLY" fetchSize="1" resultClass="Integer" parameterClass="Integer">
		SELECT	COUNT( FVGIDPRO )
		FROM 	${DBALIAS}.FVGPROJT
		WHERE 	FVGIDMOD = #idModelo#
	</select>
	
	<select id="obter_ProjetosPorModelo" resultSetType="FORWARD_ONLY" fetchSize="50" resultMap="ProjetoResult" parameterClass="Integer">
		<include refid="_selectProjeto" />
		WHERE	FVGIDMOD = #idModelo#
		AND 	FVGIDPRF IS NULL 
		<include refid="_orderByNomeProjeto" />
	</select>

</sqlMap>
Classe AbstractProjeto.
package br.com.cvrd.igrm.dao.comum;

import java.sql.SQLException;
import java.util.List;

import br.com.cvrd.igrm.to.IProjetoTO;
import br.com.cvrd.igrm.util.AbstractDAO;
import br.com.cvrd.igrm.util.PersistenceException;

/**
 * <p >
 * Template das classes de persistência das entidades dos projetos do modelo base e
 * corporativo.</p>
 * 
 * @author  Anaximandro de Godinho.
 * @version $Revision: 1.2 $
 */
public abstract class AbstractProjetoDAO extends AbstractDAO
{
   /*/ constantes públicas /*/
   public static final String P_Projeto     = "Projeto.";
   public static final String P_ProjetoBase = "ProjetoBase.";

   /**
    * Construtor.
    * @param namespace o namespace do xml do sqlMaps a ser utilizado.
    */
   public AbstractProjetoDAO( final String namespace )
   {
      _obter_Projeto = namespace + "obter_Projeto";
      _obter_ProjetoPorIdAlternativo = namespace + "obter_ProjetoPorIdAlternativo";
      _obter_ProjetoPorNome = namespace + "obter_ProjetoPorNome";

      _contar_ProjetosRaiz = namespace + "contar_ProjetosRaiz";
      _obter_ProjetosRaiz = namespace + "obter_ProjetosRaiz";

      _contar_ProjetosPorProjetoPai = namespace + "contar_ProjetosPorProjetoPai";
      _obter_ProjetosPorProjetoPai = namespace + "obter_ProjetosPorProjetoPai";

      _incluir_Projeto = namespace + "incluir_Projeto";
      _alterar_Projeto = namespace + "alterar_Projeto";
      _excluir_Projeto = namespace + "excluir_Projeto";
   }

   /**
    * Retorna o TO com os dados da linha da entidade projeto correspondente à chave fornecida.    
    *
    * @param  idProjeto a chave do projeto.
    * @return o TO com os dados da linha da entidade projeto correspondente à chave fornecida.
    * @throws PersistenceException
    */
   public IProjetoTO obterProjeto( final Integer idProjeto ) throws PersistenceException
   {
      try
      {
         return (IProjetoTO) _sqlMap.queryForObject( _obter_Projeto, idProjeto );
      }
      catch( final SQLException e )
      {
         throw new PersistenceException( e );
      }
   }

   /**
    * Retorna o TO com os dados da linha da entidade projeto correspondente à chave alternativa fornecida.    
    *
    * @param  idAlernativo a chave alternativa do projeto.
    * @return o TO com os dados da linha da entidade projeto correspondente à chave alternativo fornecida.
    * @throws PersistenceException
    */
   public IProjetoTO obterProjetoPorIdAlternativo( final String idAlternativo ) throws PersistenceException
   {
      try
      {
         return (IProjetoTO) _sqlMap.queryForObject( _obter_ProjetoPorIdAlternativo, idAlternativo );
      }
      catch( final SQLException e )
      {
         throw new PersistenceException( e );
      }
   }

   /**
    * Retorna o TO com os dados da linha da entidade projeto correspondente ao nome fornecido.    
    *
    * @param  nomeProjeto o nome do projeto.
    * @return o TO com os dados da linha da entidade projeto correspondente ao nome fornecido.
    * @throws PersistenceException
    */
   public IProjetoTO obterProjetoPorNome( final String nomeProjeto ) throws PersistenceException
   {
      try
      {
         return (IProjetoTO) _sqlMap.queryForObject( _obter_ProjetoPorNome, nomeProjeto );
      }
      catch( final SQLException e )
      {
         throw new PersistenceException( e );
      }
   }

   /**
    * Retorna a quantidade de linhas na entidade projeto com projetos no raiz.
    * 
    * @return a quantidade de linhas na entidade projeto com projetos no raiz.
    * @throws PersistenceException
    */
   public int contarProjetosRaiz() throws PersistenceException
   {
      try
      {
         return ( (Integer) _sqlMap.queryForObject( _contar_ProjetosRaiz ) ).intValue();
      }
      catch( final SQLException e )
      {
         throw new PersistenceException( e );
      }
   }

   /**
    * Retorna uma lista de TOs com os dados das linhas da entidade projeto com projetos no raiz.
    * 
    * @return uma lista de TOs com os dados das linhas da entidade projeto com projetos no raiz.
    * @throws PersistenceException
    */
   public List obterProjetosRaiz() throws PersistenceException
   {
      try
      {
         return _sqlMap.queryForList( _obter_ProjetosRaiz );
      }
      catch( final SQLException e )
      {
         throw new PersistenceException( e );
      }
   }

   /**
    * Retorna a quantidade de linhas na entidade projeto com o idProjetoPai fornecido.
    * 
    * @param  idProjetoPai a chave do projeto pai.
    * @return a quantidade de linhas na entidade projeto com o idProjetoPai fornecido.
    * @throws PersistenceException
    */
   public int contarProjetosPorProjetoPai( final Integer idProjetoPai ) throws PersistenceException
   {
      try
      {
         return ( (Integer) _sqlMap.queryForObject( _contar_ProjetosPorProjetoPai, idProjetoPai ) ).intValue();
      }
      catch( final SQLException e )
      {
         throw new PersistenceException( e );
      }
   }

   /**
    * Retorna uma lista de TOs com os dados das linhas da entidade projeto com o idProjetoPai fornecido.
    * 
    * @param  idProjetoPai a chave do projeto pai.
    * @return uma lista de TOs com os dados das linhas da entidade projeto com o idProjetoPai fornecido.
    * @throws PersistenceException
    */
   public List obterProjetosPorProjetoPai( final Integer idProjetoPai ) throws PersistenceException
   {
      try
      {
         return _sqlMap.queryForList( _obter_ProjetosPorProjetoPai, idProjetoPai );
      }
      catch( final SQLException e )
      {
         throw new PersistenceException( e );
      }
   }

   /**
    * Inclui uma linha na entidade projeto com os dados do TO fornecido.    
    * 
    * @param  projeto o TO com os dados a incluir, exceto o campo chave.
    * @return o TO com a chave da linha incluída.
    * @throws PersistenceException
    */
   public IProjetoTO incluirProjeto( final IProjetoTO projeto ) throws PersistenceException
   {
      try
      {
         final Integer key = (Integer) _sqlMap.insert( _incluir_Projeto, projeto );
         projeto.setIdProjeto( key );
         return projeto;
      }
      catch( final SQLException e )
      {
         throw new PersistenceException( e );
      }
   }

   /**
    * Altera os dados da linha da entidade projeto correspondente à chave fornecida.    
    * 
    * @param  projeto o TO preenchido com os dados a alterar, inclusive sua chave.
    * @return a quantidade de linhas alteradas.
    * @throws PersistenceException
    */
   public int alterarProjeto( final IProjetoTO projeto ) throws PersistenceException
   {
      try
      {
         return _sqlMap.update( _alterar_Projeto, projeto );
      }
      catch( final SQLException e )
      {
         throw new PersistenceException( e );
      }
   }

   /**
    * Exclui a linha da entidade projeto correspondente à chave fornecida.    
    * 
    * @param  idProjeto a chave da linha a excluir.
    * @return a quantidade de linhas excluídas.
    * @throws PersistenceException
    */
   public int excluirProjeto( final Integer idProjeto ) throws PersistenceException
   {
      try
      {
         return _sqlMap.delete( _excluir_Projeto, idProjeto );
      }
      catch( final SQLException e )
      {
         throw new PersistenceException( e );
      }
   }

   /*/ constantes privadas /*/
   private final String _obter_Projeto;
   private final String _obter_ProjetoPorIdAlternativo;
   private final String _obter_ProjetoPorNome;

   private final String _contar_ProjetosRaiz;
   private final String _obter_ProjetosRaiz;

   private final String _contar_ProjetosPorProjetoPai;
   private final String _obter_ProjetosPorProjetoPai;

   private final String _incluir_Projeto;
   private final String _alterar_Projeto;
   private final String _excluir_Projeto;
}
L

eu vi que no seu insert você chama a sequence antes de fazer o insert, so que no meu caso a sequence vai ser disparada por uma trigger no banco de dados eu tenho que fazer com que o valor gerado pela “trigger” retorne para mim.

Um exemplo com JDBC puro seria assim:

String sql = insert into A(NAME) values(something);

CallableStatement ps = this.conn.prepareCall(begin +sql+ returning ID into ?; end;);

ps.registerOutParameter(1, Types.VARCHAR);

ps.executeUpdate();

System.out.println(ID=+ps.getString(1));

existe alguma forma de fazer isto com o iBatis ?

agodinho

luciano_guedes_antunes:
eu vi que no seu insert você chama a sequence antes de fazer o insert, so que no meu caso a sequence vai ser disparada por uma trigger no banco de dados eu tenho que fazer com que o valor gerado pela “trigger” retorne para mim.

Um exemplo com JDBC puro seria assim:

String sql = insert into A(NAME) values(something);

CallableStatement ps = this.conn.prepareCall(begin +sql+ returning ID into ?; end;);

ps.registerOutParameter(1, Types.VARCHAR);

ps.executeUpdate();

System.out.println(ID=+ps.getString(1));

existe alguma forma de fazer isto com o iBatis ?

se vc estiver usando oracle cuidado com as trigger mutantes!!!

porquê que vc precisa fazer isso??? trigger gerando sequence??? explica um pouco isso pra vermos se dá pra fazer alguma outra coisa …

L

como eu falei no inicio o banco de dados contem toda a regra de negocio dos nossos sistemas portanto nos temos triggers que fazem com que as sequences sejam atribuidas, por exemplo eu nao hora de um insert eu nao passo a chave primaria passo somente os campos requeridos pela tabela a trigger que esta por traz dessa tabela que faz o trabalho de atribuir a chave primaria para o registro que estou fazendo insert portanto para mim seria fundamental fazer com que na hora do insert o valor que fosse gerado pela trigger fosse devolvido para mim a nivel de front-end (tela), quanto as triggers mutantes nao e motivo de preocupacao todas as nossas triggers estao em perfeito funcionamento sem mutantes
nao ha motivo para preocupacao.

agodinho

uma soluação possível para o que vc está querendo fazer:

  1. vc vai fazer seu insert normalmente.
  2. o banco, em meio ao insert, vai executar sua trigger e atualizar/calcular os campos necessários.
  3. normalmente o ibatis, para operação de insert, retorna a chave primária criada só que como isso foi feito pela trigger não sei se esse retorno vai realmente conter o valor da trigger - melhor testar.
  4. em último caso, se o retorno não corresponder ao id da trigger, vc pode, no dao, buscar a linha incluída.

Acho melhor testar pra não quebrar a cara.

Te adianto que pra campos obrigatórios vc fai ter que ainda específica-los nos sqls pois no momento de sua execução o banco não sabe o quê a trigger faz e, como de costume, irá reclamar da ausência de valores pra esses campos.

Esse é o comportamento do Oracle, não sei qual banco vc está usando.

L

como faco para buscar a linha incluida no dao basta fazer um select ? pelo que ? se a chave e gerada pelo banco de dados.

agodinho

select mesmo.

vc tem todos os outros dados no transfer object, se isso não for suficiente ou vc não tiver uma chave alternativa (normalmente o nome) vc então tem um problema. Perceba que isso não tem nada a ver com iBatis, mas sim com a sua forma de trabalho.

L

uma outra situação que temos aqui é a seguinte:

ItemPedido -> Tabela

NumPedido NumItemPedido
1 1
2 1
2 2

a chave primaria desta tabela é NumPedido + NumItemPedido sendo que o NumItemPedido é uma trigger que gera (sem mutante) no after como fazer neste caso ? faco um select tambem para recuperar o valor ?

agodinho

cara, seu item de pedido não tem nenhum outro campo que possa ser utilizado pra identificá-lo?

Sua trigger gera apenas o número do item de pedido certo? então vc poderia, no dao, buscar todos itens desse pedido e deduzir qual das linhas retornadas é o seu item …
Isso é medonho!!!

Não consigo parar de pensar na possibilidade de jogar fora essas triggers e chamar o chamar o nextval nos inserts direto. Acho que seria muito mais fácil pra vc.

Qual a necessidade de se manter essas trigger? Qual o esforço pra remover essas trigger e fazer que sua vida social não corra sérios riscos de ser extirpada??? :sunglasses:

L

nao é so os pedidos o banco inteiro tem estes tipos de construcao ou seja as situacoes sao muitas, estou procurando a melhor solucao estou seriamente disposto a abandonar qualquer framework de persistencia e usar o JDBC puro mesmo por exemplo utilizando o JdbcTemplate do spring o que voce acha ?

L

eu faria isso.

E não acredite em quem fale que JDBC puro é só pra sistemas simples e não comerciais. Aqui na empresa usamos assim, e pode acreditar, as aplicações aqui não são nem um pouco simples, muito pelo contrário.

Frameworks ORM são excelentes. Mas pra este seu caso, você pode começar a ter q contornar(fazer gambiarra) as limitações do framework para esse seu caso, e isso pode virar um inferno.

[]'s

L

concordo vou partir para o JDBC puro com o JdbcTemplate do spring.

E quanto a camada de visualização o Struts2 e a melhor opção para o meu caso ou tenho dar uma olhada em outras opções ?

jgbt

se suas regras estão todas no banco, acho que utilizar um framework ORM so vai acrescenar complexidade aoseu projeto.
sugiro usar JDBC com o DaoSupport do Spring. se quiser utilise o controlde de transações do Spring que funciona muito bem tmb, deixando vc livre para se preocupar com sua logica de negocio.

quanto a camada de visão, utilizei bastante o WebWork(atual Struts2), por isso acho uma boa escolha.

[]'s

L

como faco o controle de transacoes no spring para o meu caso que vai ser somente jdbc ?

agodinho

Isso não é competição. É minha opinião.
Antes de mandar uma frase dessa pense bem.

Cara, pode-se fazer um prédio com palitos e outro com tijolos não é mesmo???
Mesmo no prédio com tijolos depende-se muito da mão de obra …
Não acredito em desenvolvedor estrela, acredito em equipe. Para projetos grandes vc tem de pensar no melhor pra equpe (ou fábrica).

jdbc puro, isso é fato, aumenta a quantidade de código consideravelmente …
quanto maior a quantidade de código maior o esforço na manutenção.

agodinho

Cara, acho que vc ainda pode tirar proveito do iBatis. Vou tentar com o exemplo de código que vc mandou (estilo call exec).

Posto aqui e depois vc vê se te atende ou se vc gosta.

Até o final da madruga eu posto algo aqui (positivo ou negativo).

W

O iBatis ajuda exatamente nisso. Todos seus sqls ficarão em arquivos XMLs simples. Vc ainda terá uma camada de persistência (DAO) mas sua camada não fala jdbc. Ela simplismente delega isso pro ibatis.
Vc, ira usar Spring DAO.

http://blog.empas.com/ahnyounghoe/read.html?a=13432899&c=1130709
http://diesil-java.blogspot.com/2006_06_01_archive.html


http://ibatis.apache.org/javadownloads.cgi
sds.

agodinho

WilliamSilva:
O iBatis ajuda exatamente nisso. Todos seus sqls ficarão em arquivos XMLs simples. Vc ainda terá uma camada de persistência (DAO) mas sua camada não fala jdbc. Ela simplismente delega isso pro ibatis.
Vc, ira usar Spring DAO.

http://blog.empas.com/ahnyounghoe/read.html?a=13432899&c=1130709
http://diesil-java.blogspot.com/2006_06_01_archive.html


http://ibatis.apache.org/javadownloads.cgi
sds.

Verdade, o iBatisDAO foi descontinuado por ser redundante. O iBatisDAO é uma outra bibilioteca que ficava acima do sqlMaps que mencionei. O iBatis é hoje apenas o sqlMap. Pelo que lembro o iBatisDAO era nada mais nada menos que o quê o spring faz com os templates de DAO, daí então a galera do iBatis achou melhor descontinuar.

O exemplo de código que postei (código de produção) usa apenas o ibatis.

Nunca usei o iBatis com o spring. Mas fico meio ressabiado só de pensar numa aplicação orientada à banco com ioc.
Quando disse camada DAO tinha em mente uma camada DAO java mesmo (vide código).

W

Nunca usei o iBatis com o spring. Mas fico meio ressabiado só de pensar numa aplicação orientada à banco com ioc.
Pode explicar pq. vc. ficaria ressabiado por usar o spring Dao "“org.springframework.orm.ibatis.SqlMapClientFactoryBean”, Ele continua sendo um DAO : http://www.springframework.org/docs/reference/orm.html
http://www.oreilly.com/catalog/springadn/excerpt/springadn_ch05_81-90.pdf
A próxima versão do iBATIS prevê o uso de POJOs e annotations.
Mais pode-se usar somente "iBATIS SQL Maps " e para melhorar o desempenho o OSCache.:
http://www.onjava.com/pub/a/onjava/2005/02/02/sqlmaps.html?page=1
(Ps. qualquer semelhança desse artigo SQLMaps c/ a publicação de mesmo título em uma revista brasileira não é conhecidência é plagio e tradução não autorizada.)
http://www.opensymphony.com/oscache/

agodinho

WilliamSilva:
Pode explicar pq. vc. ficaria ressabiado por usar o spring Dao
Pode ser bobeira minha, tento sempre partir pro mais simples quando se trata de trabalhar com aplicações orientadas à banco, essas velharias sempre me pegam desprevinido. Me sinto como se estivesse tentando socar um triângulo dentro de um quadrado …

Olha só o caso desse post, tô pensando até em abrir outro post só pra ver a opinião da galera sobre esse lance de atualizar sequence dentro de trigger e tal …

Tem tudo a ver com minha assinatura não tem não?

Me pergunto o seguinte: pra quê que eu preciso de uma factory de beans para uma camada DAO que está usando iBatis? Mesmo no caso simples de utilizar um DAO Factory com iBatis, na minha opinião, isso já seria redundante. Teria de criar interfaces para DAOs que não teriam variação de código simplesmente porque a porção que poderia vir a variar (os sqls em si) já está fora desses DAOs.

W

Dependendo da abordagem isso é uma discussão sem fim.:
Começando com o modelo de SGBDs Relacionais, que tem um monte de DBAs que ainda vivem de querer re-inventar a roda com "tabelas normalizadas na 1º, 2º, 3º Normal Form e esquecem que há mais Formas, e depois que ficarem perdidos com tantos MERs errados (raros conhecem Modelo de dominio) ijá que existe a desnormalização vamos usar e,isso vem acontecendo muito ultimamente e, é interessante principalmentequando vc. revê alguns conceitos “acadêmicos” ( nunca levei a sério algumas colocações que me foram passadas na Universidade- pelos professores) quando lê um artigo assim " http://blog.fragmental.com.br/2006/08/24/bases-de-dados-sao-recursos/ " , e ai vc. começa a ver que existem mais coisas que alguns DBAs deveriam olhar com mais atenção, alguns links abaixo expressam a sua observação porèm devo dizer que hà controversias e como vc, disse é assunto para um outro post.
http://blog.michaelnascimento.com.br/2006/08/30/vale-a-pena-abstrair/
http://blog.michaelnascimento.com.br/2006/09/22/vale-a-pena-abstrair-parte-2/
http://blog.caelum.com.br/2006/08/26/ei-como-e-o-seu-dao-ele-e-tao-abstraido-quanto-o-meu/
http://blog.caelum.com.br/2006/12/17/design-patterns-um-mau-sinal/
sds.

agodinho

WilliamSilva:
Dependendo da abordagem isso é uma discussão sem fim.
Seria tão mais fácil se tudo nessa área fosse ou preto ou branco não acha?

Vou dar uma olhada no material que vc linkou, mas te adianto que, na minha opinião, nem sempre vale a pena abstrair bases legadas para um novo sistema oo. Sei que isso é uma simplificação absurda mas na correria do dia a dia é o que eu acabo fazendo.

Agora te pergunto: vc acha que sempre vale a pena usar essa abordagem quando estamos desenvolvendo um novo sistema com uma base legada? uma base que vc não pode alterar ?

Obrigado pelos links …

ainda estou devendo o exemplo com a trigger no iBatis …

Criado 25 de outubro de 2007
Ultima resposta 27 de out. de 2007
Respostas 46
Participantes 13