• Nenhum resultado encontrado

Java e MongoDB. Há muito tempo se utilizava arquivos sequenciais. mongodb_. O desenvolvimento de uma aplicação

N/A
N/A
Protected

Academic year: 2021

Share "Java e MongoDB. Há muito tempo se utilizava arquivos sequenciais. mongodb_. O desenvolvimento de uma aplicação"

Copied!
8
0
0

Texto

(1)

mongodb_

Java

e MongoDB

O desenvolvimento de uma

aplica-ção onde seja requerido o

arma-zenamento de grandes volumes

de dados pode ser bastante custoso

não só para o tempo de

desenvolvi-mento, mas principalmente para a

manu-tenção do sistema e também para

a infraestrutura. Neste artigo,

é mostrado como utilizar

o MongoDB, um banco

de dados NoSQL com Java

utilizando o Morphia nesta

comunicação.

H

á muito tempo se utilizava arquivos sequenciais

para armazenamento de dados (os famosos ar-quivos .dat), depois veio a migração para banco de dados relacional. Desde esta última evolução, nun-ca houve questionamento em relação ao modelo de banco de dados a ser utilizado, o questionamento, quando havia, era sobre a compra de licença ou do expertise das equipes da empresa em trabalhar com um ou outro banco de dados.

Após problemas de escalabilidade, custo e per-formance, muitas empresas começaram a pesquisar e a investir em novos mecanismos de armazenamen-to. Entre elas: Facebook com o Cassandra, Google com o BigTable e Linkedin com o Voldemort.

Tais bancos de dados são considerados NoSQL, onde não existe obrigatoriedade quanto ao modelo !" # $%&"!%'()')(#%"*+#%" !"'#,!-#%"!"%./!0#%1"2%'#%" também não suportam joins entre as “tabelas”.

3")0"!(($&"4$"!4'#4'$&".$4%5 !(#("6)!",#%'#"!%-colher um banco de dados NoSQL que esteja na moda e este resolverá todos os seus problemas quanto a escalabilidade. Existem alguns modelos de bancos de dados e cada qual focado em resolver um ou mais problemas, vide quadro “Tipos de bancos de dados NoSQL”.

O objetivo deste artigo é mostrar ao leitor como

trabalhar na prática com Java e MongoDB, que é um banco de dados NoSQL orientado a documentos e um dos mais genéricos dos bancos de dados NoSQL.

Utilizar um banco de dados relacional em um sistema que terá um grande volume de acessos até há alguns anos poderia ser a única solução, incluin-do neste cenário muito dinheiro com licenças de sof-twares, arquiteturas complexas e times de especia-listas a preço de ouro.

A partir de meados da década de 90, começaram mais fortemente as pesquisas sobre formas alterna-tivas de armazenamento de dados que não tivessem como base os bancos de dados relacionais.

Entre essas soluções, pode-se citar: banco de dados orientado a documentos, banco de dados $(5!4'# $%"#"$,7!'$%&",#4.$" !" # $%"./#8!98#-$("!" tabular. Tais soluções começaram a ser utilizadas de forma comercial focadas na solução de alguns :($,-!0#%",!0"!%:!.;*.$%&".$0$&":$("!+!0:-$&"#(-mazenar dados em cache, ou seja, em vez de buscar dados do banco de dados ou mesmo de arquivos em disco, no caso de arquivos estáticos, poderia se “lan-<#("0=$>" #")'5-5?#<=$" !")0",#4.$" !" # $%"./#8!9 valor em memória com persistência em disco para acelerar a entrega deste conteúdo. Um banco de da-dos que desempenha muito bem este papel é o Redis.

(2)

Marcio Garcia “Mangar” | marcio.mangar@gmail.com | @mangar

Bacharel em Ciência da Computação. Trabalha com Java desde 1996. Já trabalhou em empresas de pequeno e grande porte bem !"!#$%&'%()$#*!#+'&$,-#.#/($%'0-,&#1.$.*2!-2.*1!3#",4'&*1!#.#,*%.4'&*1!#$,$%."&$#."#5&2&3#67%8!*#.#9(:7#!*#9&,-$;#6!$$(,# .'%,<-cações SCJP, SCWCD, SCBCD, SCEA I e CSM. Atualmente, é desenvolvedor de Software freelancer, e mantém dois blogs: http://blog. mangar.com.br e http://marciogarcia.com No entanto, utilizar um banco de dados como

este como alternativa a um banco de dados rela-cional é praticamente impraticável, principalmen-te considerando a utilização de um banco de dados orientado a documentos como o MongoDB.

Um banco de dados orientado a documentos é o que mais se assemelha a um banco de dados relacio-nal, mas com a vantagem, no caso dos NoSQL, de não %!":(!4 !("#")0"!%6)!0#"*+$" !"'#,!-#%1

Bancos de dados NoSQL, embora não sejam ACID, são muito rápidos na resposta a queries e es-caláveis horizontalmente. Ou seja, para problemas de performance na aplicação, de forma geral, basta # 5.5$4#("4$8#%"0@6)54#%"4$"A-)%'!("B"$)"C$# D#-lancer dependendo da arquitetura seguida.

Neste artigo, é considerada a utilização do Mon-E$FD1" G0" ,#4.$" !" # $%" ,#%'#4'!" .$4*@8!-&" .$0" uma equipe de desenvolvimento e uma comunidade bastante ativa que ajuda na localização e correção de bugs. Vamos começar pela instalação do MongoDB.

Iniciando com o MongoDB

Vamos iniciar obtendo o binário do banco de da-dos. O MongoDB está disponível gratuitamente para praticamente todas as plataformas, Windows, Linux, H#.1" I!%'!" #('5E$" 8#0$%" -5 #(" .$0" #" 8!(%=$" H#.9 Linux. Pouquíssimos ajustes são necessários para funcionar no Windows e, sempre que necessário, são feitas pequenas considerações a respeito.

Toda a troca de informação entre a aplicação e o servidor do banco de dados se dá, em linhas gerais,

com troca de mensagens de texto em formato JSON.

O binário do MongoDB pode ser obtido através do site do MongoDB: /'':J99KKK10$4E$ ,1$(E9 $-wnloads. No momento que este artigo é escrito, a úl-tima versão estável é a 2.0.0. E é nela que se baseiam todos os exemplos apresentados neste trabalho.

Uma vez com o arquivo em seu computador, descompacte-o. Será necessário que manualmente sejam criados dois diretórios, que será onde os da-dos serão armazenada-dos. Por padrão, estes diretórios serão buscados pelo MongoDB dentro do diretório--raiz do seu drive. No Windows: C:\data\db, no *nix: 9 #'#9 ,1"A$0$"6)!(!0$%"0#4'!("'$ $"$"4$%%$":($-jeto sob controle, vamos criar esta estrutura dentro do nosso próprio diretório binário.

No Windows e no *nix:

0L 5("M:"HNIONPFQR9 #'#9 ,

Vamos tratar o diretório em que você descompactou o banco de dados como MONGO_DIR

Criado o diretório de dados, é hora de iniciar o banco de dados. Execute o comando:

HNIONPFQR9,5490$4E$ "SS ,:#'/" HNIONP FQR9 #'#9 ,9

Testando a instalação do MongoDB

Com o MongoDB em execução, podemos fazer um teste simples de conexão via linha de comando, #:!4#%":#(#"4$%".!('5*.#(" de que tudo está correto com o banco de dados. No Windows, apenas dê um duplo clique no executá-vel do mongo (MONGO_ FQR9D5490$4E$1!+!T&" 4$" *nix abra um novo termi-nal, e digite:

HNIONPFQR9,549 mongo

Uma vez conectado no console, ele informará a versão do MongoDB que está em execução e auto-maticamente você já esta-rá conectado ao bando de dados “test”.

Figura 1. MongoDB inicializado na porta padrão: 27017.

(3)

Vamos criar um banco de dados para armazenar os estados do Brasil. Conectado ao console do Mon-goDB, digite:

db.estados.save({‘sigla’: ‘SP’, ‘nome’: ‘São Pau-lo’})

U#(#"8!(5*.#("$"%!)",#4.$" !" # $%&" 5E5'!J" ,1!%'# $%1*4 VT

Neste momento já temos o MongoDB instalando e funcionando perfeitamente. Vamos ver agora o pro-cesso de comunicação e manipulação de dados atra-vés de uma aplicação Java.

Java e MongoDB

As informações no MongoDB são organizadas de forma diferente dos bancos de dados relacionais que estamos acostumados. Em vez de tabelas, as informa-ções são armazenadas em coleinforma-ções.

A comunicação com o servior MongoDB é feito através de socket, e a forma de troca de informação é feita nativamente através de JSON.

Para quem está acostumado com JPA, abrir um socket e trocar JSONs é um tanto estranho e com cer-teza, na utilização frequente, mesmo utilizando bi-bliotecas para facilitar a geração e interpretação de JSON, este procedimento se mostrará bastante traba-lhoso além de improdutivo.

Em vez disso, utilizaremos um dos drivers mais maduros e independentes para comunicação entre uma aplicação Java e o MongoDB, o Morphia. Exis-tem outros drivers para Java ou mesmo para Groovy, Scala, Clojure, JRuby e várias outras linguagens que rodam sobre a JVM. Neste artigo, é utilizado o Mor-phia, por se mostrar mais maduro e independente de frameworks externos, como é o caso do Spring Mon-goDB.

!"#$%&'"(!)!)*&!+,-!

I!%'!"#('5E$&"$":($7!'$" $":$("0!5$" $"H#8!41"X".$4*E)(#<=$"#"%!("54%!(5 #" no seu pom.xml é esta:

Listagem 1.

Dependência do MavenDepCriando e obtendo registro via console do MongoDB.

<dependency>

<groupId>com.google.code.morphia</groupId> <artifactId>morphia</artifactId>

<version>0.99</version> </dependency>

Caso você não utilize Maven em seus projetos e :(!*(#"W#?!("$" $K4-$# " 5(!'#0!4'!" $" (58!(&"8@" 5-reto à área de download no site do Morphia.

Vamos começar a detalhar o funcionamento das operações de inclusão, alteração, exclusão e seleção de registros (o famoso CRUD), apresentando um có-digo bastante simples, mas que abrange cada uma das operações básicas utilizando MongoDB com Morphia. Após este primeiro contato, teremos um pouco mais de familiaridade para evoluir com criação de índices, busca avançada de registros e referências.

Um CRUD de exemplo

Iniciando pelo básico, vamos detalhar uma classe que obtém, insere, atualiza e exclui registros de uma coleção. A listagem completa pode ser obtida no site da MundoJ, e vamos mostrar aqui as partes mais re-levantes do nosso primeiro CRUD. Vamos utilizar um objeto chamado Estado. Esta é uma classe anotada com @Entity que representa a nossa coleção. Neste ponto, apenas utilizaremos esta classe. No próximo tópico, vamos descrever os itens mais importantes no mapeamento entre objeto vs. coleção.

Comecemos pela conexão com o banco de dados. Esta deve ser feita utilizando um objeto do tipo Da-tastore, onde é passado como parâmetro um objeto do tipo Mongo, que pode receber como parâmetro o endereço do servidor e a porta de conexão. Vamos )'5-5?#(" $" .$4%'()'$(" :# (=$" !" )'5-5?#(" #%" .$4*E)(#-ções padrão. O segundo parâmetro é o nome do ban-co de dados a ser ban-conectado.

Todo código da Listagem 2 até a Listagem 7 está na classe mg.mundoj.mongodb.AppMorphiaSimple.

Listagem 2.

Conexão com o servidor MongoDB. private Datastore ds;

private Mongo mongo;

publicAppMorphiaSimple() throws Exception { mongo = newMongo();

ds = newMorphia().createDatastore(mongo, “test”);

}

Assim que concluímos a instalação do servidor MongoDB, inserimos um registro na coleção chama-da “estados”. Pois bem, vamos consultar novamente a nossa coleção e obter este registro dentro da apli-cação. Vamos utilizar o método get(). Este método retorna o primeiro registro da coleção.

Listagem 3.

Obtendo o primeiro registro da coleção “Estados”.

publicvoidgetFirst() {

Estado e = this.ds. !"(Estado.class).get();

System.out.println(e.sigla + “ - “ + e.nome); }

(4)

Vamos ver como inserir um registro em nossa co-leção. Para salvar um novo registro, basta inicializar uma classe mapeada para uma coleção e acionar o método save(Entity) da classe Datastore.

Listagem 4.

Inclusão do registro na coleção: estados. publicvoidcreateOne() {

))))./-'(!)&+)0)newEstado(“RJ”, “Rio de Janeiro”); ds.save1&+23

}

Com mais um registro na coleção estados, vamos obter todos os registros que já estão presentes nesta utilizando um novo elemento, a classe Query. Este objeto é criado a partir do Datastore. O primeiro pa-râmetro é a Entity. Após, obtemos a listagem de todos $%"(!E5%'($%"%!0"4!4/)0"*-'($"#'(#8Y%" $"0Y'$ $"#%-List() da classe Query.

Listagem 5.

Obtendo todos os registros da coleção. publicvoidgetAll() {

Query query = ds.createQuery(Estado.class);

List<Estado> listaEstados = q.asList();

for (Estado estado : listaEstados) { System.out.println(estado.sigla + “ - “ + estado.nome);

} }

Excluir um documento é uma tarefa bem simples e pode ser executada por meio do objeto Query, como exibido na Listagem 6. Os detalhes do funcionamento do objeto Query são descritos mais adiante, onde é tratada a busca de documentos.

Listagem 6.

Excluindo um documento. publicvoiddeleteLast() {

Query query = ds.createQuery(Estado.class). #$"(“sigla”).equal(“RJ”);

ds.delete(q); }

A atualização de um documento é executada em três passos: encontrar o documento a ser alterado, fazer a #-'!(#<=$"!"*4#-0!4'!"!485#("$" $.)0!4'$"#$"%!(85-dor. A Listagem 7 mostra todas essas etapas.

Listagem 7.

Atualizando um documento. publicvoidupdateSP() {

Query q = ds.createQuery(Estado.class). #$"(“sigla”). equal(“SP”);

UpdateOperations<Estado> estadosUpdate = super.ds.createUpdateOperations( Estado.class).set(“nome”, “Sao Paolo”);

ds.update(q, estadosUpdate);

}

Agora, com os primeiros passos de como manipular registros na base de dados do MongoDB, vamos dar uma olhada mais detalhada em cada uma dessas eta-pas, iniciando pelo mapeamento entre uma classe e uma coleção no banco de dados.

4'*,'5,"-!)(')."-6('(,)7)89+,-!):)

Documento

Em nosso primeiro exemplo, Listagens 2 a 5 uti--5?#0$%")0"$,7!'$"./#0# $"2%'# $1"2%'!"$,7!'$"*.$)" responsável por mapear o objeto e o documento no banco de dados, nesta parte, vamos detalhar como este mapeamento pode ser feito e como o Morphia trata este mapeamento.

Nossa entidade foi criada como mostrado na Lis-tagem 8. Utilizamos três anotações do MongoDB para fazer este mapeamento.

» @Entity: responsável pelo mapeamento entre a classe e o documento no banco de dados. Op-cionalmente recebe o primeiro parâmetro que é o nome da coleção no MongoDB.

» @Id: parecida com a @Id da JPA. Esta é a chave primária do nosso documento.

» @Property: esta anotação faz o mapeamen-to similar à @Entity, mas no nível de campos do nosso documento. A anotação é opcional, e caso ela seja omitida, o Morphia fará o ma-peamento de mesmo nome entre o campo do objeto e o campo no documento.

Listagem 8

!"#$%&' (%)%!*!+%,-%.-/$'!-/$0-!'1(-$'! e documento.

@Entity(“estados”) publicclass Estado {

@Id

public!21(-3$4&!5&6

@Property(“sigla”) public String sigla;

public String nome;

}

@Reference ! @Embedded: veremos com detalhes a seguir campos anotados como @Reference e @ Embedded servem como apontamento ou “chaves estrangeiras” para outros documentos.

(5)

adiante, esta anotação cria um índice para o campo em questão. Bastante útil quando exis-te carga elevada de consulta baseada no campo em questão.

» @Transient: campos com esta anotação não serão persistidos no documento.

» @Serialized: o conteúdo do objeto será arma-zenado em um campo binário.

» @NotSaved: este campo não será armazena-do no banco de daarmazena-dos, apenas transferiarmazena-do armazena-do documento para o objeto. Comportamento diferente do @Transient que, além de não ser armazenado no banco de dados, também não será carregado.

Ainda existem algumas anotações dedicadas ao ciclo de vida da entidade sendo ativadas sempre que um objeto é enviado ao servidor ou recebido do ser-vidor. Estas anotações atuam como callback para o método anotado.

» @PrePersist: chamado imediatamente antes do objeto ser salvo no banco de dados.

» @PostPersist: chamado logo após o MongoDB "#$%&'(& ( )*"&+,( -# -#".')$,# $# /($"# -) dados.

» @PreLoad: chamado antes de popular o obje-to com os valores do documenobje-to no banco de dados.

» @PostLoad: chamado logo após os campos do objeto serem populados com os valores do do-cumento.

Os métodos de callback anotados com @PrePer-sist e @PostPer@PrePer-sist podem receber um parâmetro do tipo DBObject, que é uma cópia do documento que está sendo trabalhado no momento, antes ou depois de gravar no banco de dados. Pode-se ver as assinatu-ras e a utilização das anotações na Listagem 9.

0 1#**23)4 (+$-( -)%$+& '(+* -) .' '5,#-# -) callback para cada evento, por exemplo, pode-se ter mais de um callback @PrePersist para uma mesma entidade. Não existem ainda métodos de callback para registros a serem excluídos.

Listagem 9.

"#$%&' (%)%!*!+7$'&'#!&-!8%991%3:!;

@PrePersist

voidprePersist<21(-3$!&121(-3$=!>

System.out.println(“@PrePersist .... “ + newDate()); }

@PostPersist

voidpostPersist<21(-3$!&121(=!>

System.out.println(“@PostPersist .... “ + newDate()); }

@PreLoad voidpreLoad() {

System.out.println(“@PreLoad .... “ + newDate()); }

@PostLoad voidpostLoad() {

System.out.println(“@PostLoad .... “ + newDate()); }

Adicionalmente, pode-se utilizar a anotação @ EntityListeners informando como parâmetro uma classe com os métodos anotados referentes ao ciclo de vida da entidade. Desta forma, a classe de modelo $6# %"(&7 1#4.2-( "#' )3)$,.(+* ,(&)8(* (-'+$+*,&(-tivas ou genéricas para todos os modelos, como, por )9)'14#: -)%$+& .'( -(,( 1(-&6#; <(&( +*,#: ($#,) ( classe da entidade com @EntityListener passando como parâmetro o nome da classe que implementará #* '5,#-#* -) "(44/("=; 0 '#*,&(-( $( >+*,(?)' @A esta classe.

Listagem 10.

!"#$%&'")-/$?5#$-/-0 (%)%!*!89%##-! -@$-0/%!3'.!'#!.7$'&'#!&-!3%991%3:!&-A/5&'#

publicclass EstadoEventListener {

@PrePersist

voidprePersist<21(-3$!&121(-3$=!> System.out.println(“@PrePersist @

EstadoEventListener .... “ + newDate()); } }

!"!#$%&'()*+*, !"!#!%&!*-*,

Embedded

B('#* '#-+%"(& .' 1#."# $#**# )9)'14# -) )*-tados e adicionar mais duas novas entidades: Cidade e Bairros. Ou seja, um estado poderá ter mais de uma cidade e uma cidade poderá ter zero ou vários bairros.

Ambas as anotações são bastante autoexplica-tivas: enquanto a @Reference cria uma referência entre um documento e outro, a @Embedded cria um documento dentro de outro. Vamos ver na prática como funciona uma e outra, a começar por @Refe-rence.

B-C-0D/35%!-/$0-!&'3E.-/$'#!*!;B-C-0-/3-Uma referência entre documentos é a criação de um link (foreign key) entre um documento e outro. Em nosso exemplo, vamos utilizar @Reference entre as entidades Cidade e Estado. Na Listagem 11 é mos-trada a estrutura da entidade Cidade, e na Listagem 12 a utilização desta referência.

Listagem 11.

!85&%&- (%)%!F!"/$5&%&-!85&%&-!3'.! referência à entidade Estado.

@Entity(“cidades”) publicclass Cidade {

(6)

@Id

public!21(-3$4&!5&6

public String nome;

@Reference public Estado estado;

}

Listagem 12.

!G,,85&%&-B-C-0-/35% (%)%!F!H$595I%/&'! a anotação @Reference entre cidades e estados.

protectedvoidcriarCidades() {

Estado sp = ds..%/(Estado.class)..!0/(“sigla”). equal(“SP”).get();

Cidade cidade = newCidade(); cidade.nome = “Sao Paulo”; cidade.estado = sp; super.ds.save(cidade); }

protectedvoidlistarCidades() {

for (Cidade cidade : super.ds..%/(Cidade.class)) { System.out.println(cidade);

} }

protectedvoidalterarSP() {

Query<Estado> q = super.ds.createQuery(Estado.class). .!0/(“sigla”).equal(“SP”);

UpdateOperations<Estado> estadosUpdate = super.ds.createUpdateOperations( Estado.class).set(“nome”, “São Paulo”);

super.ds.update(q, estadosUpdate);

}

publicstaticvoidmain(String[] args) throws Exception { AppCidadeReferencia app = newAppCidadeReferencia(); app.criarCidades(); app.listarCidades(); app.alterarSP(); app.listarCidades(); }

Repare que tínhamos um registro no documento de estado: sigla: SP nome: Sao Paolo. Criamos uma nova cidade e associamos a ela este estado. Em um segundo momento, foi alterado o nome deste estado para o nome correto: São Paulo. Quando executamos o método: app.listarCidades() novamente, o nome do estado foi alterado de fato para todas as cidades que tinham uma referência para este estado.

Agora, em nosso banco de dados, existem duas coleções de documentos: estados e cidades.

J'3E.-/$'#!".1E$5&'#!*!;".1-&&-&

Outra modalidade de referência de documentos são os documentos embutidos, anotados com @Em-bedded. Estes não possuem uma coleção física fora da entidade pai, ou seja, se tentar obter uma listagem via console desta coleção, não será possível. O principal motivo é que este documento referenciado está pre-sente apenas no objeto pai.

Voltando para nosso exemplo, vamos criar um @ Embedded para os bairros de uma cidade. No trecho de código a seguir é mostrada esta alteração na classe Cidade.java.

@Embedded

public List<Bairro> bairros;

Pode-se ver na Listagem 13 que o objeto Bairro não possui um campo com a anotação @Id e nem a ano-tação de classe @Entity, por se tratar de um docu-mento que apenas faz parte do docudocu-mento Cidade, e fora deste contexto, o documento Bairro não existe. Este é apenas um POJO.

Listagem 13.

!K%500' (%)%!F!&'3E.-/$'!5/$-0/'!%'! '1(-$'!85&%&-

publicclass Bairro {

public String nome;

}

<#-)C*) 3)& $( %?.&( D # &)*.4,(-# %$(4 -( "#4)E6# de cidades após a utilização dos bairros como @Em-bedded.

Obtendo registros (documentos)

Os documentos são obtidos do banco de dados por meio da interface Query. Existem duas formas -) *) #/,)& #* -#".')$,#*F 1)4# '5,#-# %4,)&: #. -) .'( 8#&'( '(+* 4)?23)4: )*1)"+%"($-# "('1# ( "('-1#: "&+,5&+# ( "&+,5&+# G( "H('(-( +$,)&8(") I.)$,)J;

K )*"#4H( -( 8#&'( -) .,+4+L(E6# %"( ( "&+,5&+# -# leitor, e não existe benchmark com a informação de M.) .' '5,#-# 5 '(+* )%"+)$,) M.) # #.,&#; N M.) %"( "4(&# #4H($-# 1(&( # "O-+?# 5 M.) ( 8#&'( I.)$,) é mais legível. Desta forma, também é possível criar queries dinâmicas, observando os parâmetros de en-trada quando utilizado um DAO, por exemplo.

Na Listagem 14 é mostrada a classe AppQuery e a utilização do Filter, e na Listagem 15, na mesma clas-*): '(* "#' ( .,+4+L(E6# -( 8#&'( I.)$,);

Listagem 14.

!G,,LE-0M (%)%!F!1E#3%!&-!&'3E.-/$'#! utilizando Filter.

publicvoid.01!#2'/(/!345)1(/6(String sigla) { Estado estado = super.ds.createQuery( Estado.class)..01!#(“sigla =”, sigla).get();

(7)

Query<Cidade> q = super.ds.createQuery( Cidade.class)..01!#(“estado =”, estado); ..

}

Listagem 15.

!G,,LE-0M (%)%!F!1E#3%!&-!&'3E.-/$'#! utilizando Interface Fluente.

publicvoid78!%12'/(/!345)1(/6(String sigla) { Estado estado = super.ds.createQuery(Estado.class). .!0/(“sigla”).equal(sigla).get();

Query<Cidade> query = super.ds.createQuery( Cidade.class);

query..!0/(“estado”).equal(estado); ..

for (Cidade cidade: query.fetch()) { System.out.println(cidade); }

}

Dependendo do que é esperado como retorno, um método do objeto Query deve ser chamado. Por exemplo, se você espera que apenas um registro seja retornado na query, chame o método get(). Veja abai-xo os resultados possíveis.

» get(): retorna apenas um objeto, o primeiro da listagem.

» asList(): retorna uma lista de objetos como re-sultado.

» fetch(): obtém um Iterable de objetos.

» asKeyList()F &),#&$( .'( 4+*,( -) "H(3)!3(4#& com apenas o Id do objeto. Muito útil e rápido quando é necessário apenas o Id do objeto. » fetchEmptyEntities(): um mix entre o fetch()

e o asKeyList(), este retorna uma lista contendo apenas o Id do objeto.

As duas formas mais utilizadas são o get() e o fetch(), exibidos na Listagem 15. Os demais serão deixados como exercício para o leitor avaliar as reais utilidades das mesmas.

Operadores

A listagem completa de operadores pode ser ob-tida no site do Morphia (na tabela 1 são mostrados

#* 1&+$"+1(+* #1)&(-#&)* ) ( &)4(E6# )$,&) %4,)& ) ( +$,)&8(") I.)$,)J; Filter Fluente = Equal !=, <> notEqual > greaterThan < lessThan >= greaterThanOrEq <= lessThanOrEq

Tabela 1. Relação dos operadores.

Ordenação de registros

A ordenação dos registros acontece chamando-se # '5,#-# #&-)&GJ $# %$(4 -# %4,&# -( M.)&P; Q) 8#& $)-cessário informar mais de um campo para ordenação, basta separá-los por vírgulas. Por padrão, a ordena-ção é feita em ordem ascendente, e para inverter a ordem (descendente), basta incluir o caracter “-“ no começo do campo. Na Listagem 16 é mostrada a utili-zação do método order e suas opções.

Listagem 16.

!G,,20&-0 (%)%!F!20&-/%NO'!&'#!&'3E-mentos.

publicvoidshowOrderByNome() {

Query<Cidade> q = super.ds.createQuery(

Cidade.class).order(“nome, estado.sigla”); for (Cidade c: q.fetch()) {

System.out.println(c); }

}

publicvoidshowDescOrderByNome() { Query<Cidade> q = super.ds.createQuery( Cidade.class).order(“-nome”);

for (Cidade c: q.fetch()) { System.out.println(c); }

}

Limit e Offset

Limit e Offset são duas opções bastante úteis quando é necessário, por exemplo, mostrar registros agrupados ou em quantida--)* -)%$+-(* 1#& 17?+$(*; K utilização é bastante pareci-da com a ordenação, incluin-do a chamada de um métoincluin-do !"# $%"&$"'()*+,"-."/( 01)." Offset e Limit podem ser uti-lizadas juntas para que a pa-ginação possa ocorrer na ca-mada do banco de dados. Na Listagem 17 é mostrado como utilizar ambas as funções.

Figura 3. Coleções de cidades e estados em nosso banco de dados.

(8)

!"#3+)45!(!)**+,--6#17/%##%87/6#0-+-0#3+)45-/referências

Listagem 17.

!""#$%$&'(()*&+,-.- / 0&$1$2-345 6* Limite e Offset.

publicvoidall() {

System.out.println(“\n--- all() --- “);

Query<Cidade> q = super.ds.createQuery(Cidade.class); for (Cidade c: q.fetch()) {

System.out.println(c); }

}

publicvoidlimit(int no) {

System.out.println(“\n--- limit(“ + no + “) --- “);

Query<Cidade> q = super.ds.createQuery(Cidade.class).

limit(no);

for (Cidade c: q.fetch()) { System.out.println(c); }

}

publicvoidoffset(int no) {

System.out.println(“\n--- offset(“ + no + “) --- “);

Query<Cidade> q = super.ds.createQuery(Cidade.class).

offset(no);

for (Cidade c: q.fetch()) { System.out.println(c); }

}

publicvoidoffsetLimit(int noO, int noL) {

System.out.println(“\n--- offsetLimit(“ + noO + “,” + noL + “) --- “);

Query<Cidade> q = super.ds.createQuery(Cidade.class). offset(noO).limit(noL);

for (Cidade c: q.fetch()) { System.out.println(c); }

}

!"#$%&'()*&#+,"($#

A utilização de um banco de dados orientado NoSQL depende, e muito, das características de cada aplicação e suas necessidades e limites técnicos e não-técnicos. O Morphia é uma alternativa muito produtiva em comparação com o driver nativo Java para o MongoDB. Sua curva de aprendizado para quem está acostumado a trabalhar com JPA é bastan-te reduzida.

A parte mais difícil é se adaptar ao mecanismo orientado a documentos do MongoDB, que acredi-2!" .)*" 3(4acredi-2!" 5*$24#6$ 2)7" 8*4 648$%3) 2)" '($ acredi-2!" $!" tempo de desenvolvimento e manutenção da apli-6$09!7"$8:.".)"$&'(4*4*";(< 64$" $"3$ )4*$"6!3!"!." documentos podem ser manipulados.

Tipos de bancos de dados NoSQL

Existe alguns tipos de bancos de dados NoSQL, cada um destinado a solucionar um problema ).8)6=#6!,">."?$ 6!."&)"&$&!."!*4) 2$&!."$"&!-cumentos estão tomando cada vez mais força no âmbito comercial. Entre suas principais carac-terísticas, está a escalabilidade vertical de fácil manutenção e instalação. Para startups e sites de grandes volumes de manipulação de dados, a utilização de bancos de dados NoSQL orientado a documentos podem ser a solução mais adequada. Os principais modelos de bancos de dados NoS-QL são:

Orientado a documento: MongoDB, CouchDB, MarLkogic Server, BaseX, sXist

Orientado a objetos: Db4o

@A$B)CB$%!*D"E)36$6A)&FG7"H*!I)62"J!%&)3!*27" Rdis, SimpleDB, Hbase

Tabular: Cassandra, Hypertable K*L#6!D"M)!NI7"FOP

75895:; * !<=: / !&5%$>$6-6*?@<58)$)&A8>$-?@=)5-1-%*8&5 *@:BC-D$1$6-6*

No desenvolvimento do MongoDB foram prio-rizadas algumas funcionalidades (Flexibilidade, Facilidade e Velocidade) em detrimento de ou-tras (Transações).

O MongoDB não suporta transações ACID. Pelo menos não de forma nativa entre coleções, como os bancos de dados relacionais suportam entre tabelas. O MongoDB oferece suporte a ACID na-tivamente quando as alterações são entre docu-mentos aninhados, mas não entre coleções. Para os casos em que são necessárias controle de transações entre coleções, é possível, através de uma camada intermediária entre a aplicação e o banco de dados.

Referências

Documentos relacionados

No final, os EUA viram a maioria das questões que tinham de ser resolvidas no sentido da criação de um tribunal que lhe fosse aceitável serem estabelecidas em sentido oposto, pelo

The DCF model using the Free Cash Flow to the Firm (FCFF) method, estimates in the first place the Enterprise Value of the company, that represents the value of all future cash

Taking into account the theoretical framework we have presented as relevant for understanding the organization, expression and social impact of these civic movements, grounded on

Outras possíveis causas de paralisia flácida, ataxia e desordens neuromusculares, (como a ação de hemoparasitas, toxoplasmose, neosporose e botulismo) foram descartadas,

Por fim, na terceira parte, o artigo se propõe a apresentar uma perspectiva para o ensino de agroecologia, com aporte no marco teórico e epistemológico da abordagem

O artigo tem como objeto a realização, em 2013, do Congresso Internacional Justiça de Transição nos 25 anos da Constituição de 1988 na Faculdade de Direito da UFMG, retratando

O fortalecimento da escola pública requer a criação de uma cultura de participação para todos os seus segmentos, e a melhoria das condições efetivas para

O caso de gestão estudado discutiu as dificuldades de implementação do Projeto Ensino Médio com Mediação Tecnológica (EMMT) nas escolas jurisdicionadas à Coordenadoria