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

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

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?

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

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.

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.

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.

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.

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

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

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

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

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

O primefaces me dá apenas o front-end.

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

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

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:

Chegou a ver esse link??

1 curtida

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.

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.

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ó?

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…

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.