Upload de arquivo .xlsx para banco através de Aplicação Java

25 respostas
infraestruturaprimefacesjava
R

Galera, gostaria de fazer um upload de arquivos xlsx para o meu banco através da minha aplicação java, sendo da seguinte maneira.

O usuário seleciona o arquivo através de um botão “escolher arquivo” e realize o upload de forma que a aplicação só passe o arquivo para o banco e ele trate de tudo para não pesar o servidor da aplicação.

Eu achei alguns post, mas eles eram ou através de caminhos onde os arquivos estavam ou através da aplicação e não do banco.

Banco: Oracle
Aplicação: Java
JDBC: EclipseLink

25 Respostas

D

Existem duas formas de você armazenar arquivos em um servidor: gravando-os no filesystem ou gravando em uma tabela/coluna do banco (estamos falando de SGBD relacional).
Qual o problema da primeira abordagem (a que você mais encontrou exemplos por aí afora): permissão para escrita/leitura e dificuldade com compressão (nem tanto, o java pode comprimir para ti).
A segunda abordagem é, teoricamente, mais complexa. Você precisa pegar o arquivo e converter em um formato que seja legível pelo SGBD. Como não sabe o tamanho dos arquivos, precisa, de algum modo, que o banco de dados não refute o mesmo por ser muito grande.
Para isso, os bancos de dados trabalham com dois tipos: CLOB e BLOB, que é maior que o CLOB.
Com relação às limitações, aqui a questão de espaço é idêntica à da forma mais usual. Um arquivo é, nada mais que, um array de bytes. E 1 giga em um array de bytes ou em um “arquivo” é a mesma coisa
Pesar o servidor? Que tipo de processamento está pensando? Afinal, os fatores que “pesam” o servidor (ou o teu computador pessoal) são os mesmos:

  • Memória
  • Processador
  • Disco rígido
  • Placa mãe
    Dificilmente você terá outros elementos que possam causar (não que não exista) lentidão, mas estes são os principais vilões.
    Será que não está faltando uma boa especificação a respeito disso, não?
D

Achei isso intrigante. JDBC: EclipseLink? Oi? É isso mesmo? Ou você está usando ORM com implementação do EclipseLink?

R

A persistência de dados está sendo implementada através do EclipseLink, outro exemplo seria o Hibernate, posso ter me equivocado ao falar JDBC.

O servidor que aloca a aplicação e o banco de dados são diferentes, e pelo do banco de dados ser mais robusto eu queria passar o processamento dos dados pro mesmo, fazendo com que a aplicação fosse apenas um intermediário.

D

Isso só seria possível se o banco de dados fosse manipular o arquivo. Não sou conhecedor a ponto de afirmar que o oracle seja capaz de fazer isso.
De qualquer maneira, a possibilidade que vejo é receber o array de bytes e jogar o mesmo na tua base, então. Afinal, o arquivo vai como array de bytes, você só pega e repassa ele.

R

Não entendi o que você quis dizer com manipular.
Mas através do Oracle SQL Developer eu consigo fazer a inserção de um .xlsx sem problemas, acho que devido a isso o BD suporte sim.

D

Você disse:

Imaginei que você quisesse fazer algum tipo de ação com o arquivo, além de, unicamente, colocar o mesmo numa tabela.
Se é essa a ideia, o EclipseLink até torna isso bem mais fácil para ti.

R

Eu não preciso fazer nenhuma alteração no mesmo, somente o upload.

De que maneira eu faço isso então?

D

Entendi.
Estamos falando de aplicação web, certo? Está usando o que nesta aplicação? JSF? Rest?

R

Aplicação web.
Utilizo JSF primefaces.
Servidor GlassFish
Banco Oracle
EclipseLink

D

O primefaces possui um componente para upload. Creio que o exemplo deles seja o mais simples de implementar.
Dá uma olhada e tenta aí.

R

O primefaces me dá apenas o front-end.

Eu quero saber como passar da aplicação pro banco…

D

Quais as outras exigências que o sr tem a fazer mesmo?

R

Eu não quero nada pronto amigo, eu disse que não achei em nenhum lugar algo que se aplique ao que eu quero e vim aqui atrás de um norte de como fazer. :slight_smile:

A

Chegou a ver esse link??

D

Assim fica melhor.
Primeiro, você entende que todo e qualquer arquivo é, nada mais, que um grande array de bytes?
Sendo assim, quando você realizar o upload deste arquivo, o primefaces envia um amontoado de dados, junto a algumas coisas (informações que ele acha necessárias).
Veja o exemplo que sugeri, lá tem o objeto que transporta o arquivo e como recuperar ele no managed bean.

Além disso, você precisa ter uma entidade em que um dos atributos seja um array de bytes, mapeado como @Lob, se não me engano.
A partir daí, é só associar uma coisa a outra e mandar gravar no banco.

D

Conforme a documentação do UploadedFile do primefaces, ele contém um método que permite obter só o array de bytes.
Ou seja, é moleza fazer a parte de gravar.

R

Vi a documentação aqui e não entendi uma coisa, o array de bytes é de cada coluna ou do arquivo todo como um só?

R

Ele faz exatamente o que eu não quero, passa na aplicação o aquivo e manda pro banco linha por linha, eu gostaria de mandar o arquivo todo e o banco realizar as inserções…

D

Deixa eu tentar explicar melhor.
Como eu disse antes, cada arquivo é um imenso array de bytes. O array em si é o arquivo.
Assim sendo, você dificilmente armazena um arquivo numa coluna do tipo varchar ou text (mysql ainda tem este tipo?).
O correto é inserir em uma coluna do tipo BLOB (existem outros, mas este é o mais utilziado).
Assim sendo, o array de bytes deve ser armazenado em uma única coluna.

R

Entendi o que você quis dizer agora, mas acho que eu que me dei a entender mal…

Eu disse que não iria haver a manipulação do arquivo, mas era durante o processo de inserção, depois eu irei precisar sim manipular todos os dados que eram contidos naquele arquivo.

Desculpe.

Estou achando que a solução vai ser passar linha por linha como se estivesse fazendo um cadastro na aplicação…

D

O arquivo salvo no BD, mesmo sendo um array de bytes, ainda é o arquivo.
Assim sendo, a qualquer tempo, você pode carregar esse array em memória e criar um arquivo temporário, o qual poderá ser lido, alterado, etc.

A

Entendi, que pena… mals ai!

R

O que eu estou querendo fazer é o seguinte.

Um arquivo excel que tenha por exemplo:

Coluna1 | Coluna2
Teste | Exemplo
Teste1 | Exemplo1
Teste2 | Exemplo2

Seja passado pra um banco que vai ter as mesmas colunas como espelho e vai receber esses dados.
Coluna1 | Coluna2

Para fazer isso eu achei inúmeras soluções, só que eu percebi que iria reter uma grande requisição do servidor da aplicação, pois todas pegavam uma linha, mandavam pro banco, pegavam a próxima…

Ai me ocorreu que se fosse possível mandar o arquivo pro banco e ele interpretasse tudo e fizesse os inserts nas colunas, como se fosse a aplicação.
Para depois pela aplicação eu conseguir acessar esses dados e realizar manipulações…

Fui mais claro agora?
Foi apenas uma ideia que eu tive e quis saber se era possível fazer :slight_smile:

D

É, se é esta a situação, a coisa fica mais complicada. Todas as ações demandam ler o arquivo, linha a linha, montar uma query gigantesca e mandar inserir (isso se não for inserindo linha a linha) no banco de dados.

R

Entendi, muito obrigado pelo seu tempo :slight_smile:

Criado 17 de janeiro de 2018
Ultima resposta 18 de jan. de 2018
Respostas 25
Participantes 3