BISMO

De BIS Wiki
Revisão de 15h07min de 7 de setembro de 2015 por Rodrigogml (discussão | contribs) (Rodrigogml moveu a página MatchObject para BISMO sem deixar um redirecionamento)
Ir para navegação Ir para pesquisar

A utilização do MO é bem simples se toda a camada de persistência for desenvolvida com base na estrutura do BISCore. De acordo com o nome do atributo criado no VO e no MO, a camada de persistência 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, criamos no MO um atributo chamado "eq_name". o prefixo "eq" significa equals, indicando que queremos os objetos cujo o atributo seja igual ao valor passado no MO e "name" qual é o atributo do VO que desejamos a comparação. Usamos o carácter "_" para separar o comando do atributo.

A lista de comandos aceitos estão no tópico abaixo, e os atributos são sempre iguais aos definidos no VO. Tendo criado o atributo no MO, não se esqueça de criar os métodos Get e Set correspondentes.

Classe dos Atributos do MO

A classe que define o atributo no MO deve ser o mesmo definido no VO. No exemplo dado da String name no VO, os atributos de comparação no MO devem ser String também. Exceto comandos específicos como por exemplo de tamanho da String, que neste caso deve ser definida como Inteiro. Para detalhes consulte a tabela de comandos.

Atributos com "_" no nome
Como o MO utiliza o carácter "_" para separar os comandos ou VOs em cadeia, não é possível utilizar "_" no nome do atributo no VO e fazer buscas utilizando o MO.

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 que o MO tenha pelo menos dois atributos:

  • mask_name: do tipo String, que deve ser definida com o valor "Rodrigo%", para que busquemos todos os contatos cujo nome comecem com "Rodrigo";
  • eq_address_city_name: também do tipo String, e deve ser definida como "Campinas". Para que busquemos todos os contados que estão com o endereço na cidade de "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.

Limite de VOs em Cadeia
Há um limite de VOs em cadeia que se pode usar para a busca, que é o tamanho máximo dos atributos do Java, ou do nome dos métodos de Get e Set - já que tem sempre 3 letras a mais que o nome do atributo.

Em casos cujo o filtro fique muito grande, talvez seja conveniente dividir a busca em mais de uma consulta, já que ao carregar tantos objetos em cadeia fará a camada de persistência popular muitos objetos que podem não ser desejados, só causando tráfego e processamento desnecessário.

Lista de Comandos do MO

Dos comandos utilizados pelo MO, muitos devem ser da mesma classe que o atributo definido no VO, porém, alguns tem um tipo de atributo fixo, devendo-se usar a definição da tabela.

Atributos definidos como null
Qualquer atributo definido como NULL é desconsiderado pelo comparados do BISCore. Para buscar objetos que tenham algum atributo nulo utilize o comando isnull definindo como TRUE ou FALSE de acordo como desejado.


Comandos do MO
Comando Significado Classe do Parametro Detalhes
eq equals <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.
neq not equals <Mesmo do VO> Inversão do modo de comparação equals. Faz com que o objeto tenha que ser diferente do definido.
ge greater or equals <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.
gt greater than <Mesmo do VO> Compara dois valores numéricos. Faz com que o valor dos VOs retornados sejam maiores que os valor definido no MO.
le less or equals <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.
lt less than <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 is null Boolean Se definido como true retorna os objetos cujo atributo esteja nulo. Se false, retorna os objetos cujo atributo NÃO esteja definido como nulo.
mask mask of pattern 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.
maskor mask of pattern Collection<String> Similar ao comando mask, mas permite receber uma lista de patterns e compara o mesmo atributo com todas os padrões definidos. O VO é retornado se o atributo for compatível com qualquer um dos padrões.
maskand mask of pattern Collection<String> Similar ao comando mask, mas permite receber uma lista de patterns e compara o mesmo atributo com todas os padrões definidos. O VO é retornado se o atributo for compatível com todos os padrões.
in 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.
nin not 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 NÃO estiver na lista passada, ou seja, se o valor for diferente de todos os itens da lista.
neqand not equal / and 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. (Mesmo efeito que o comando "nin", exceto que usa uma série de concatenações de NOT EQUAL ao montar a query ao invés de usar o comando "not in".

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.