Como manter um mesmo sistema para clientes diferentes (bancos de dados diferentes)

A empresa onde eu trabalho desenvolve um sistema web que atualmente está disponível para um único cliente. Futuramente vamos disponibilizar o mesmo sistema para outros clientes, mas é fundamental que cada cliente tenha acesse acesse o sistema com um banco de dados diferente. Por exemplo, um usuário do cliente A loga informando sua empresa (A), login e senha, utilizando o sistema com o banco de dados A. Já um usuário do cliente B loga informando sua empresa (B), login e senha, utilizando o sistema com o banco de dados B.

O sistema é feito usando Struts 1.x e Hibernate 3.2. Seria interessante que o sistema fosse disponibilizado em um único .WAR, de forma que, ao fazer o deploy no Tomcat, todos os clientes tivessem acesso a mesma versão do sistema.

Alguém tem alguma sugestão? :slight_smile:

abraços!

Olá,

Banco de dados diferente acho que gera uma gambiarra, ou uns ifs malucos na hora de passar o caminho do banco de dados para a aplicação.

Que que você acha de criar mais uma tabela no seu sistema chamada Empresa (ou Cliente), sendo relacionada com sua tabela de usuario, assim, qualquer tabela do sistema terá o id Empresa (ou Cliente) estará nas outras tabelas do sistema. Ao fazer um select, update, delete, insert leva em consideração o id da empresa nessas operações.

Abraços

É uma boa solução, mas gostaríamos de deixar as informações em bancos separados por uma questão de segurança. Não queremos correr o risco de um usuário do cliente A visualizar em um relatório uma informação estratégica do cliente B.

Eu não sei se o Hibernate possibilita “flexibilizar” o seu arquivo de configuração, de forma que ele escolha qual banco de dados utilizará baseado em um parâmetro. Ele também deveria criar um SessionFactory para cada banco/cliente, não sei se alguma dessas coisas é possível.

abraços!

abraços,

bonfarj,

Você pode criar na parte administrativa uma área para criar/configurar um projeto, e ter uma tabela no banco que guarde as informações do nome banco, como nome do banco, host, usuario e senha (criptografada, é claro), relacionado com a tabela empresa.

E quando o usuário entrar no sistema ele seleciona qual a empresa, e você passa os parametros configurados para o Hibernate.

                 Configuration ac = new AnnotationConfiguration()
 	// Package dos POJOs
 	.addPackage("br.com.app.model.pojo")
 	// Classes POJOs (Entidades do sistema)
 	.addAnnotatedClass(Entidade1.class)
 	.addAnnotatedClass(Entidade2.class);
 	// Configurações de acesso ao PostgreSQL
 	//.setProperty("hibernate.show_sql", "true")
 	.setProperty("hibernate.dialect", DB_DIALECT)
 	.setProperty("hibernate.connection.driver_class", DB_DRIVER_CLASS)
 	.setProperty("hibernate.connection.url", db_url)
 	.setProperty("hibernate.connection.username", DB_USERNAME)
 	.setProperty("hibernate.connection.password", DB_PASSWORD);

Acho que isso resolve seu problema.

Qualquer problema, poste.

Olá, descupa me entrometer, mas eu acho que devem haver vários bancos sim, por que serão empresas diferentes, só deverá haver um banco se for uma filial dessa empresa.
Por que? Por que as empresas cadastrarão e manipularão os dados pertinentes à elas, e não lhes interessará os dados de outras empresas, só se houver um intercâmbio entre elas, e além disso, você manter um banco de dados com dados de diferentes empresas será difícil, por que o banco inchará de maneira exponencial.
Mas eu concordo em criar uma tabela, ou até outro banco que conterá dados da empresa, como nome ou razão social, cnpj, login e senha, usuários, e o sistema acessando primeiro esse banco ou tabela, e depois de confirmada a empresa, o login e a senha, o sistema ser redirecionado para o banco da empresa desejada. 
As classes de fonteira e de controle serão as mesmas, só mudará o banco, e ainda você pode trabalhar com outros SGBD's, pois você pode armazanar na tabela a url do SGBD's.
Entendeu?
Acho que desse jeito é muito melhor, dará trabalho para implementar esse acesso, mas depois poupará tempo.

Valeu pelas opiniões, pessoal, está me ajudando muito! Em relação ao que o fsquadro postou, como ficaria em relação ao SessionFactory? No nosso sistema as configurações do Hibernate estão dentro de um arquivo XML, o nosso SessionFactory é criado assim:

protected static final SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

Ou seja, ele só é criado no primeiro acesso. Queria saber como ficaria isso na sua solução, se apenas um SessionFactory cuidaria de mais de um banco ou se haveria um SessionFactory para cada banco/cliente.

abraços!

Com certeza os dados da empresa z so podem ser manipulados e interessam a mesma :smiley:

Mas com uma tabela empresa no banco de dados e fazendo o MER corretamente isso acontecerá como conseguencia da sua modelagem!

Não entendi o porque da crítica.
Bancos diferentes você começa a se complica, pense no backup! Talvez com duas empresas não! Agora pense qué é um sistema que diversos clientes estão utilizando, uns 30 + ou -, terá 30 bancos de dados?! Vai replicar tudo? triggers, procedures, usuarios, … Se o produto (Sistema) é o mesmo sem nenhuma particularidade, porque separar od DBs?!

E outra vem seu departamento de venda e fala: “Conseguimos mais um cliente” e você conseguentemente pensa “vou dar MAIS um ctrl+c ctrl+v no meu banco…” Trabalho braçal né?!
Com uma tabela, você adiciona esse cliente e pronto… o sistema ta novinho em folha para ele.

Espero que tenha entendido!
Abraços Pessoal

Oi Paulo, realmente o que vc falou faz todo sentido, bem observado. Pensei em deixar apenas uma “instância” do sistema para que quando ela fosse atualizada todos os clientes ficariam com o sistema atualizado. Mas com vários bancos isso vai por água abaixo, pois se alguma atualição impactar no banco (ex: adicionar uma coluna em uma tabela), terei que rodar um script SQL em cada banco.

No entanto, o nosso sistema tem um tamanho razoável, são mais de 100 tabelas, algumas tabelas chegam a dezenas de milhares de registros em um mês. Um um único banco de dados para todos os clientes, além da questão da segurança que é importantíssima, o desempenho pode ficar comprometido com muitos clientes. Claro que um bom tunning e um sgbd rápido e robusto ajudam, mas é inegável que o desempenho fica melhor com um banco de dados com apenas um cliente.

Algum de vocês já vivenciou uma situação parecida? Se alguém tiver tido uma experiência dessas não deixe de contar aqui! :slight_smile:

Vou escrever um documento mostrando todas as opções que nós temos, com prós e contras. Não tenham dúvidas que a ajuda de vocês está sendo fundamental para mim, muito obrigado mesmo!

abraços!

Bonfarj,

tenho um sistema (rodando há uns dois anos) nesse esquema que você quer.

Criei um .war (cada cliente tem 1 .war idêntico).
Cada .war “aponta” para um BD diferente.

Preferi também não juntar todas as instituições
clientes num “BDZÃO”…rrsrsrsrr

Pois isso iria dificultar, no meu caso, a rapidez das informações,
se bem que acessando alguns relatórios do sistema -
via conexão discada - meu tempo de resposta
varia entre 4/5 segundos (é uma extranet) !!!

Realmente essa duplicação exige muito “trabalho braçal” o tal ctrl + c
e ctrl + v, entretanto para issso não ocorrer e necessário torcer
para seus diferentes tipos de clientes/empresas não peçam muitas
atualizações.

Resumindo: Não tenho o que reclamar do Ctrl + c e Ctrl + v.

Abs.

oi feaupi!

Legal saber disso, fiquei curioso em relação a alguns pontos:

1 - Qual o servlet container que você usou nesse sistema, foi o Tomcat mesmo?

2 - Você usou uma mesma instância do servlet container e fez o deploy dos arquivos .WAR em contextos diferentes?

3 - Como você direciona a requisição do usuário no browser até o “sistema correto”?

abraços!

Vou aproveitar a carona, tambem estou numa situação parecida, tem um sistema que foi feito aqui na empresa que possui uma base de dados oracle, so que tem uma outra base que esta em SQL, por falta de tempo para pegar os dados da base sql e jogar na base oracle, temos que fazer esse sistema pegar as informações das bases diferentes mesmo, acessar os dois bancos, gostaria de uma instrução como proceder.

Obrigado

[quote=lucastody]Vou aproveitar a carona, tambem estou numa situação parecida, tem um sistema que foi feito aqui na empresa que possui uma base de dados oracle, so que tem uma outra base que esta em SQL, por falta de tempo para pegar os dados da base sql e jogar na base oracle, temos que fazer esse sistema pegar as informações das bases diferentes mesmo, acessar os dois bancos, gostaria de uma instrução como proceder.

Obrigado[/quote]

Oi lucas, talvez seja melhor você abrir outro tópico, seu problema é diferente, pode criar confusão na discussão de ambos. De qualquer forma, seria melhor você passar mais informações sobre o seu sistema, vcs usam Hibernate? Não entendi qual é o banco de dados, acho que o banco SQL que vc falou na verdade é o MS SQL Server, não?

abraços,