BISMO

De BIS Wiki
Ir para navegação Ir para pesquisar

O BISMO é um MatchObject, isto é, ele carrega informações para descobrir objetos equivalentes. Em outras palavras ele permite um filtro de objetos baseados em seus atributos. Seu principal uso atual é feito pelo BISDAO para a consulta de objetos persistidos.

De acordo com o nome do atributo criado no VO, o BISDAO será capaz de retornar os objetos desejados sem mais linhas de código além do nome do atributo e seus métodos GET e SET.

Por exemplo, imaginando que tenhamos os objetos ContactVO para representar um contato. E que um dos atributos presente no VO seja uma String "name". Para buscar os VOs pelo conteúdo do seu atributo "name" exatamente, devemos criar uma instância do BISMO e definir que queremos que "name" seja igual ao valor desejado:


Java 256.png Exemplo Criação BISMO para filtrar pelo valor do atributo "name"
BISMO mo = new BISMO();
mo.equals(ContractVO_.VO.name(), "João de Barros");


A lista de comandos aceitos estão no tópico abaixo, e podem ser verificadas de forma mais atualizada no próprio JavaDoc dos métodos do BISMO.

Stop 256.png
Utilização do MetaObject BISVO_
Para efeitos de compatibilidade e qualidade do sistema não passe uma String diretamente. Utilize o pattern do MetaObject BISVO_ para definir os atributos no BISMO.


VOs em Cadeia

O MO pode fazer buscas com filtros baseado nas informações próprias e de outros VOs que estejam dentro deles. Por exemplo, imagine o objeto ContactVO novamente. Imagine que dentro dele temos um atributo chamado "address" que é um AddressVO. E que por sua vez tem um atributo chamado "city" que é do tipo CityVO e dentro deste VO o nome da cidade é salva no atributo "name".

Agora, queremos obter todos os ContactVO cujo nome comecem com "Rodrigo", e que a cidade seja igual a "Campinas". Para realizar a busca com essas duas condições precisamos passar no MO os dois atributos:

Java 256.png Exemplo Criação BISMO para filtrar pelo valor do atributo "name"
BISMO mo = new BISMO();
mo.like(ContractVO_.VO.name(), "Rodrigo%");
mo.equals(ContractVO_.VO.cityvo().name(), "Campinas");

Combinando ambas as condições no mesmo MO e usando qualquer um dos métodos de busca da camada de persistência devemos obter os objetos que satisfazem ambas as condições.


Lista de Comandos do MO

Note 64.png
Atributos definidos como null
Qualquer atributo definido como NULL é desconsiderado para o filtro de comparação no BISDAO. Para buscar objetos que tenham algum atributo nulo ou não nulo, utilize respectivamente os comandos isNull e isNotNull de acordo com o desejado.


Comandos do MO
Comando Classe do Parametro Detalhes
equal <Mesmo do VO> Utiliza o modo de comparação equals do java ou o = do banco de dados. Faz com que um objeto tenha de ser exatamente igual à outro.
notEqual <Mesmo do VO> Inversão do modo de comparação equals. Faz com que o objeto tenha que ser diferente do definido.
greaterThanOrEqualTo <Mesmo do VO> Compara dois valores numéricos. Faz com que o valor dos VOs retornados sejam maiores ou iguais ao o valor definido no MO.
greaterThan <Mesmo do VO> Compara dois valores numéricos. Faz com que o valor dos VOs retornados sejam maiores que os valor definido no MO.
lessThanOrEqualTo <Mesmo do VO> Compara dois valores numéricos. Faz com que o valor dos VOs retornados sejam menores ou iguais ao o valor definido no MO.
lessThan <Mesmo do VO> Compara dois valores numéricos. Faz com que o valor dos VOs retornados sejam menores que os valor definido no MO.
isNull <Nenhum> Se definido retorna os objetos cujo atributo esteja nulo.
isNotNull <Nenhum> Se definido retorna os objetos cujo atributo não esteja nulo.
like String Este comando é semelhante ao 'like" do banco de dados. Busca os atributos que se encaixam em um determinado padrão. Utiliza as mesmas mascaras do MySQL: % para indicar uma cadeia qualquer de caracteres, e _ para indicar um único carácter qualquer. Só funciona para conteúdos do tipo String.
in Collection<<Mesmo do VO>> Recebe uma lista de objetos da mesma classe que o atributo do VO. Retorna o VO se o valor do VO estiver na lista passada, ou seja, se o valor for igual a qualquer um dos itens da lista.
notIn Collection<<Mesmo do VO>> Recebe uma lista de objetos da mesma classe que o atributo do VO. Retorna o VO se o valor do VO NÃO estiver na lista passada, ou seja, se o valor for diferente de todos os itens da lista.


Lógica Booleana entre Operações

Por ser a mais usada, quando mais de uma condição é definida no MO a operação booleana de concatenação entre as condições padrão é o AND. Mas isso não é fixo e pode ser alterado! Caso queira que trocar o AND por OR utilize o método:

setAppendmethod(APPENDMETHOD appendmethod)

e passe o atributo:

APPENDMETHOD.OR

.

Além de alterar a condição de AND para OR, algumas vezes é necessário combinar ambas. Pra combinar diversas condições mesclando os operadores AND e OR. Como cada MO só permite trabalhar com o AND ou OR por vez, temos que montar os conjuntos em MOs separados e depois junta-los. Por exemplo, imaginemos que temos diversas condições: c1, c2, ..., cN. E queremos o resultado da expressão:

((c1 AND c2 AND c3) OR c4) AND ((c5 OR c6) AND c7)

Para este caso temos que montar as expressões em MOs separadas de acordo com os operadores lógicos usados:

  • MO1: Usando o Appendmethod = AND, definimos as condições c1, c2 e c3; [MO1 representa "(c1 AND c2 AND c3)"]
  • MO2: Usando o Appendmethod = OR, definimos a condição c4, e colocamos o MO1 na lista de submos usando o método:
    setSubmo(List<BISDefaultMO> submo)
    [MO2 representa "(MO1 OR c4)"]
  • MO3: Usando o Appendmethod = OR, definimos o c5 e c6; [MO3 representa "(c5 OR c6)"]
  • MO4: Usando o Appendmethod = AND definimos o c7 e assim como fizemos antes, colocamos o MO3 como submo deste MO; [MO4 representa "(MO3 AND c7)"]
  • MO5: Por fim, usando o Appendmethod = AND, não definimos nenhuma condição adicional, mas temos que definir os MO2 e o MO4 como submos deste MO; [MO5 representa "(MO2 AND MO4)"]

Otimizando a Consulta

Assim como no SQL, utilizando as operações booleanas para otimizar e simplificar as operações. Embora não tenhamos ainda todas as ferramentas necessárias na estrutura do MO (como por exemplo usar o NOT em um submo), algumas operações podemos realizar tranquilamente. Se analisarmos novamente a expressão anterior, podemos usar 1 objeto a menos se tirarmos os parenteses e deixamos a expressão assim:

((c1 AND c2 AND c3) OR c4) AND (c5 OR c6) AND c7

Desta maneira montaríamos os MOs da seguinte maneira:

  • MO1, MO2 e MO3 permaneceriam os mesmos;
  • No MO4 definiríamos c7 normalmente, mas passariamos MO3 e MO2 como submos;
  • MO5 não é mais necessário.

Outras lógicas podem ser aplicadas como por exemplo. Analisando a expressão acima no seguinte trecho:

c5 OR c6

e supormos que c5 e c6 sejam condições do tipo equal. A regra de lógica booleana diz que se negarmos os operandos e invertermos o operador booleano teremos a mesma tabela verdade:

A OR B = !A AND !B

assim, se c5 e c6 são condições do tipo equal sua negação é a operação not equal, disponível no MO, vamos chama-las de nc5 e nc6, assim a expressão ficaria assim:

nc5 AND nc6

o que deixa a nossa expressão completa da seguinte forma:

((c1 AND c2 AND c3) OR c4) AND (nc5 AND nc6) AND c7

observe que os parenteses em volta de nc5 e nc6 são desnecessários agora. E dessa forma podemos eliminar outro objeto (o anterior MO3), bastando para isso definir as condições c5 e c6 negadas (nc5 e nc6) diretamente no que chamamos de MO4. Usando a mesma lógica, e supondo quais seriam as condições, seriamos capaz de inverter as lógicas e remover todos os parenteses deixando apenas 1 operando, seja ele AND seja ele OR.