BISMO: mudanças entre as edições

De BIS Wiki
Ir para navegação Ir para pesquisar
Criou página com '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,...'
 
Sem resumo de edição
 
(2 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 1: Linha 1:
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.
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.


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.
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.


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.
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:


{{nota|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.}}


{{stop|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.}}
{{java|Exemplo Criação BISMO para filtrar pelo valor do atributo "name"|
<syntaxhighlight lang="java">
BISMO mo = new BISMO();
mo.equals(ContractVO_.VO.name(), "João de Barros");
</syntaxhighlight>}}


== VOs em Cadeia ==
 
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|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".
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";
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:
* '''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".
 
{{java|Exemplo Criação BISMO para filtrar pelo valor do atributo "name"|
<syntaxhighlight lang="java">
BISMO mo = new BISMO();
mo.like(ContractVO_.VO.name(), "Rodrigo%");
mo.equals(ContractVO_.VO.cityvo().name(), "Campinas");
</syntaxhighlight>}}
 
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.
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.


{{stop|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 ==
= 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.


{{nota|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.}}
 
{{nota|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.}}




{|class="wikitable" style="text-align:center; width:100%;"
{|class="wikitable" style="text-align:center; width:100%;"
!colspan="4"|Comandos do MO
!colspan="3"|Comandos do MO
|-
|-
! Comando
! Comando
! Significado
! Classe do Parametro
! Classe do Parametro
! Detalhes
! Detalhes
|-
|-
|eq
|equal
|equals
|<Mesmo do VO>
|<Mesmo do VO>
| style="text-align:left;" | 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.
| style="text-align:left;" | 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
|notEqual
|not equals
|<Mesmo do VO>
|<Mesmo do VO>
| style="text-align:left;" | Inversão do modo de comparação equals. Faz com que o objeto tenha que ser diferente do definido.
| style="text-align:left;" | Inversão do modo de comparação equals. Faz com que o objeto tenha que ser diferente do definido.
|-
|-
|ge
|greaterThanOrEqualTo
|greater or equals
|<Mesmo do VO>
|<Mesmo do VO>
| style="text-align:left;" | Compara dois valores numéricos. Faz com que o valor dos VOs retornados sejam maiores ou iguais ao o valor definido no MO.
| style="text-align:left;" | Compara dois valores numéricos. Faz com que o valor dos VOs retornados sejam maiores ou iguais ao o valor definido no MO.
|-
|-
|gt
|greaterThan
|greater than
|<Mesmo do VO>
|<Mesmo do VO>
| style="text-align:left;" | Compara dois valores numéricos. Faz com que o valor dos VOs retornados sejam maiores que os valor definido no MO.
| style="text-align:left;" | Compara dois valores numéricos. Faz com que o valor dos VOs retornados sejam maiores que os valor definido no MO.
|-
|-
|le
|lessThanOrEqualTo
|less or equals
|<Mesmo do VO>
|<Mesmo do VO>
| style="text-align:left;" | Compara dois valores numéricos. Faz com que o valor dos VOs retornados sejam menores ou iguais ao o valor definido no MO.
| style="text-align:left;" | Compara dois valores numéricos. Faz com que o valor dos VOs retornados sejam menores ou iguais ao o valor definido no MO.
|-
|-
|lt
|lessThan
|less than
|<Mesmo do VO>
|<Mesmo do VO>
| style="text-align:left;" | Compara dois valores numéricos. Faz com que o valor dos VOs retornados sejam menores que os valor definido no MO.
| style="text-align:left;" | Compara dois valores numéricos. Faz com que o valor dos VOs retornados sejam menores que os valor definido no MO.
|-
|-
|isnull
|isNull
|is null
|<Nenhum>
|Boolean
| style="text-align:left;" | Se definido retorna os objetos cujo atributo esteja nulo.
| style="text-align:left;" | 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
|isNotNull
|mask of pattern
|<Nenhum>
| style="text-align:left;" | Se definido retorna os objetos cujo atributo '''não''' esteja nulo.
|-
|like
|String
|String
| style="text-align:left;" | 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.
| style="text-align:left;" | 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>
| style="text-align:left;" | 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>
| style="text-align:left;" | 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
|in
|Collection<<Mesmo do VO>>
|Collection<<Mesmo do VO>>
| style="text-align:left;" | 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.
| style="text-align:left;" | 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
|notIn
|not in
|Collection<<Mesmo do VO>>
|Collection<<Mesmo do VO>>
| style="text-align:left;" | 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.
| style="text-align:left;" | 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>>
| style="text-align:left;" | 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 ==
 
= 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:<pre>setAppendmethod(APPENDMETHOD appendmethod)</pre> e passe o atributo:<pre>APPENDMETHOD.OR</pre>.
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:<pre>setAppendmethod(APPENDMETHOD appendmethod)</pre> e passe o atributo:<pre>APPENDMETHOD.OR</pre>.
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:
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:
<pre>'''((c1 AND c2 AND c3) OR c4) AND ((c5 OR c6) AND c7)'''</pre>
<pre>((c1 AND c2 AND c3) OR c4) AND ((c5 OR c6) AND c7)</pre>


Para este caso temos que montar as expressões em MOs separadas de acordo com os operadores lógicos usados:
Para este caso temos que montar as expressões em MOs separadas de acordo com os operadores lógicos usados:
Linha 114: Linha 106:
* '''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)"]
* '''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 ===
== 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:
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:
<pre>'''((c1 AND c2 AND c3) OR c4) AND (c5 OR c6) AND c7'''</pre>
<pre>((c1 AND c2 AND c3) OR c4) AND (c5 OR c6) AND c7</pre>


Desta maneira montaríamos os MOs da seguinte maneira:
Desta maneira montaríamos os MOs da seguinte maneira:
Linha 131: Linha 123:
<pre>nc5 AND nc6</pre>
<pre>nc5 AND nc6</pre>
o que deixa a nossa expressão completa da seguinte forma:
o que deixa a nossa expressão completa da seguinte forma:
<pre>'''((c1 AND c2 AND c3) OR c4) AND (nc5 AND nc6) AND c7'''</pre>
<pre>((c1 AND c2 AND c3) OR c4) AND (nc5 AND nc6) AND c7</pre>
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.
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.

Edição atual tal como às 17h56min de 7 de setembro de 2015

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:


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.

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:

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

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.