[quote=fabiofalci][quote=rogelgarcia]Se quiserem, podem criar um caso de uso qualquer, que seja relativamente pequeno, eu implemento e posto o código aqui no fórum para vocês verem… (tem que ser relativamente pequeno, apenas para caber aqui no fórum)
[/quote]
Existe tanto projetinho oferencedo mil maravilhas que fica difícil chamar a atenção. Por mais que vc fale que o next é isso, é aquilo, é o primeiro framework a usar tal coisa, etc. Não me convence muito.
Até olhei o site, mas sinceramente, muito texto, vídeo, etc. Que tal algo mais objetivo?
Cria uns projetinho de exemplo no github, libera pra galera baixar, fuçar e assim ver os beneficios.
[/quote]
Fala fabio, tudo bom?
Criei uma aplicação, pequena, para servir de exemplo mesmo, mas já dá pra ver alguma coisa…
Utilizei a idéia do nosso amigo que queria fazer um sistema para padaria…
Criei 2 CRUDs, sendo que um possui UPLOAD
E mais uma tela, fora do padrão…
São 5 entidades:
- Funcionario: para guardar os registros de funcionario
- Pao: para guardar os nomes e preços dos pães
- Arquivo: para guardar a foto do funcionario
- Venda: para guardar uma venda
- ItemVenda: para guardar cada item de uma venda
[color=darkblue]A aplicação consiste em um cadastro de pão.
Um cadastro de funcionário, onde deve ser possível fazer um upload para a foto do mesmo. Essa foto será mostrada tanto na tela de listagem de dados, quanto na entrada de dados.
E um formulário para cadastrar uma venda e seus itens. A venda terá uma referência para um funcionário.[/color]
A aplicação pode ser baixada em: http://www.nextframework.org/download/padaria.zip
Ela está pronta para funcionar no Tomcat 6… é só descompactar…
Tem uma pasta src com os fontes…
Para configurar o banco de dados, edite o arquivo connection.properties que está dentro de WEB-INF/classes e lembre-se de colocar o JAR do driver do seu banco de dados. As tabelas serão criadas automaticamente…
Para facilitar o trabalho, vou colocar aqui alguns códigos que tiveram alguma intervenção e imagens da aplicação:
Para funcionar o Upload, deve ser criada uma classe na aplicação que implemente File, exemplo:
@Entity
public class Arquivo implements File {
Long cdfile;
String name;
String contenttype;
byte[] content;
Long size;
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "sq_Arquivo")
@SequenceGenerator(name = "sq_Arquivo", sequenceName = "sq_Arquivo")
public Long getCdfile() {
return cdfile;
}
public String getName() {
return name;
}
public String getContenttype() {
return contenttype;
}
public byte[] getContent() {
return content;
}
public Long getSize() {
return size;
}
public void setCdfile(Long cdfile) {
this.cdfile = cdfile;
}
public void setName(String name) {
this.name = name;
}
public void setContenttype(String contenttype) {
this.contenttype = contenttype;
}
public void setContent(byte[] content) {
this.content = content;
}
public void setSize(Long size) {
this.size = size;
}
}
É uma entidade normal do hibernate, com getters e setters… Os atributos necessários estão definidos por getters e setters da interface File.
Com essa classe o upload de arquivos fica habilitado.
Para utilizar o arquivo, no Funcionario, é trivial:
...
public class Funcionario {
.... //outros atributos
Arquivo foto;
@ManyToOne(fetch=FetchType.LAZY)
public Arquivo getFoto() {
return foto;
}
.... // getters e setters
Quando um funcionário for persistido, o arquivo será detectado e todo o código necessário para a sua persistencia será executado…
Em um JSP, para criar o campo de upload para a foto, basta fazer:
<t:property name="foto"/>
Na listagem de funcionário eu farei testes na foto para verificar se ela existe e então exibir a imagem. Será necessário buscar a foto quando buscar o funcionário, então o DAO de Funcionario ficou assim:
public class FuncionarioDAO extends GenericDAO<Funcionario>{
@Override
public void updateListagemQuery(QueryBuilder<Funcionario> query, FiltroListagem filtro) {
query.leftOuterJoinFetch("funcionario.foto"); // atualizamos a query de listagem de dados para carregar também a foto
}
}
Também fiz um controller personalizado para a venda… Esse controller ficou assim:
@Controller(path="/site/Venda") //configura a URL
public class VendaController extends MultiActionController {
VendaDAO vendaDAO; // o DAO de Venda será injetado por existir um setter para ele
public void setVendaDAO(VendaDAO vendaDAO) {
this.vendaDAO = vendaDAO;
}
public ModelAndView criar(WebRequestContext request){ // Action para criar uma nova venda
request.setAttribute("venda", new Venda());
return new ModelAndView("venda"); //redirecionando para o JSP
}
public ModelAndView salvar(WebRequestContext request, Venda venda){ //Action para salvar a venda
vendaDAO.saveOrUpdate(venda); // salvamos a venda no banco de dados
request.addMessage("Venda criada com sucesso!"); //exibimos uma mensagem de sucesso
return sendRedirectToAction("criar"); //enviamos um redirecionamento para a acao 'criar'
}
}
Para salvar a venda junto com seus itens (mestre/detalhe), o DAO de Venda sofreu a seguinte alteração:
public class VendaDAO extends GenericDAO<Venda>{
@Override
public void updateSaveOrUpdate(SaveOrUpdateStrategy save) {
save.saveOrUpdateManaged("itens");//salva os itens da venda junto com a venda em apenas uma transação
}
}
Basicamente, essas foram as alterações necessárias… Os outros DAOs e Controllers ficaram no padrão, ou seja, não foi necessário codificar nada extra…
Vamos aos JSPs e telas então
Cadastro de Pão, ficou padronizado:
<%@ taglib prefix="t" uri="template"%>
<t:listagem>
<t:janelaResultados>
<t:tabelaResultados>
<t:property name="id"/>
<t:property name="nome"/>
<t:property name="preco"/>
</t:tabelaResultados>
</t:janelaResultados>
</t:listagem>
<%@ taglib prefix="t" uri="template"%>
<t:entrada>
<t:janelaEntrada>
<t:tabelaEntrada>
<t:property name="id"/>
<t:property name="nome"/>
<t:property name="preco"/>
</t:tabelaEntrada>
</t:janelaEntrada>
</t:entrada>
Cadastro de funcionário, sofreu algumas alterações para exibir e foto do Funcionario.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="n" uri="next"%>
<%@ taglib prefix="t" uri="template"%>
<t:listagem>
<t:janelaResultados>
<t:tabelaResultados>
<t:property name="id"/>
<n:column header="Foto" width="40">
<c:if test="${!empty funcionario.foto}">
<img src="${app}/DOWNLOADFILE/${funcionario.foto.cdfile}" width="32"/><!-- <t:property name="foto"/> -->
</c:if>
</n:column>
<t:property name="nome"/>
</t:tabelaResultados>
</t:janelaResultados>
</t:listagem>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="n" uri="next"%>
<%@ taglib prefix="t" uri="template"%>
<t:entrada>
<t:janelaEntrada>
<t:tabelaEntrada>
<t:property name="id"/>
<n:panel>Foto</n:panel>
<n:panel>
<c:if test="${!empty funcionario.foto}">
<img src="${app}/DOWNLOADFILE/${funcionario.foto.cdfile}"/><BR/>
</c:if>
<t:property name="foto"/>
</n:panel>
<t:property name="nome"/>
</t:tabelaEntrada>
</t:janelaEntrada>
</t:entrada>
O JSP para cadastro da venda, que foi um JSP fora do padrão:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="n" uri="next"%>
<%@ taglib prefix="t" uri="template"%>
<t:tela titulo="Venda">
<n:bean name="venda">
<t:propertyConfig mode="input" renderAs="double">
<n:panelGrid columns="2" class="inputWindow" width="100%">
<t:property name="funcionario" labelStyle="width: 100px"/>
<t:property name="data" type="hidden" write="true"/>
<n:panel colspan="2">
<t:detalhe name="itens">
<t:property name="pao"/>
<t:property name="quantidade"/>
</t:detalhe>
</n:panel>
<n:submit action="salvar">Efetuar venda</n:submit>
</n:panelGrid>
</t:propertyConfig>
</n:bean>
</t:tela>
A tag n:bean serve para podermos utilizar os t:property do bean selecionado
O n:panelGrid cria uma tabela com duas colunas para a tela ter uma organização
A tag t:propertyConfig indica a todos os t:property que eles estão em modo INPUT e deve renderizar utilizando duas colunas (DOUBLE, uma para o label, e uma para o INPUT)
A tag t:detalhe cria um detalhe (dataGrid) para a propriedade itens da venda, colocando um botão para adicionar e remover itens dinamicamente…
Acho que já dá pra ter uma noção… se tiver alguma dúvida ou curiosidade… basta perguntar…
Até mais
Obrigado