Introdução ao Spring Data Neo4j
1. Visão geral
Este artigo éan introduction to Spring Data Neo4j, o popular banco de dados de gráficos.
Spring Data O Neo4j permite o desenvolvimento baseado em POJO para o Neo4j Graph Database e usa conceitos familiares do Spring, como classes de modelo para uso principal da API, e fornece um modelo de programação baseado em anotação.
Além disso, muitos desenvolvedores não sabem realmente se o Neo4j será realmente uma boa opção para suas necessidades específicas; aqui estáa solid overview no Stackoverflow discutindo por que usar o Neo4j e os prós e contras.
2. Dependências do Maven
Vamos começar declarando as dependências do Spring Data Neo4j nopom.xml. Os módulos Spring mencionados abaixo também são necessários para o Spring Data Neo4j:
org.springframework.data
spring-data-neo4j
5.0.1.RELEASE
org.neo4j
neo4j-ogm-test
3.1.2
test
Essas dependências incluem os módulos necessários para teste também.
Observe que a última dependência tem o escopo definido como 'teste'. Mas também observe que, em um desenvolvimento de aplicativo do mundo real, é mais provável que você tenha um servidor Neo4J completo em execução.
Se queremos usar o servidor incorporado, também precisamos adicionar a dependência:
org.neo4j
neo4j-ogm-embedded-driver
3.1.2
As dependênciasspring-data-neo4j,neo4j-ogm-testeneo4j-ogm-embedded-driver estão disponíveis no Maven Central.
3. Configuração Neo4Jj
A configuração do Neo4j é muito direta e define a configuração de conexão para o aplicativo se conectar ao servidor. Semelhante à maioria dos outros módulos de dados do spring, esta é uma configuração do spring que pode ser definida como XML ou Java.
Neste tutorial, usaremos apenas a configuração baseada em Java:
public static final String URL =
System.getenv("NEO4J_URL") != null ?
System.getenv("NEO4J_URL") : "http://neo4j:[email protected]:7474";
@Bean
public org.neo4j.ogm.config.Configuration getConfiguration() {
org.neo4j.ogm.config.Configuration config = new Builder().uri(URL).build();
return config;
}
@Bean
public SessionFactory getSessionFactory() {
return new SessionFactory(getConfiguration(),
"com.example.spring.data.neo4j.domain");
}
@Bean
public Neo4jTransactionManager transactionManager() {
return new Neo4jTransactionManager(getSessionFactory());
}
Como mencionado acima, a configuração é simples e contém apenas duas configurações. Primeiro - oSessionFactory is referenciando os modelos que criamos para representar os objetos de dados. Em seguida, as propriedades da conexão com os terminais do servidor e as credenciais de acesso.
O Neo4j inferirá a classe do driver com base no protocolo do URI, no nosso caso "http".
Observe que, neste exemplo, as propriedades relacionadas à conexão são configuradas diretamente no servidor; no entanto, em um aplicativo de produção, eles devem ser adequadamente externalizados e fazer parte da configuração padrão do projeto.
4. Repositórios Neo4j
Alinhando com a estrutura do Spring Data, o Neo4j suporta o comportamento de abstração do repositório do Spring Data. Isso significa que o acesso ao mecanismo persistente subjacente é abstraído nosNeo4jRepository embutidos, onde um projeto pode estendê-lo diretamente e usar as operações fornecidas prontas para usar.
Os repositórios são extensíveis por métodos localizadores anotados, nomeados ou derivados. Suporte para repositórios Spring Data Neo4j também são baseados emNeo4jTemplate, então a funcionalidade subjacente é idêntica.
4.1. Criando oMovieRepository &PersonRepository
Usamos dois repositórios neste tutorial para persistência de dados:
@Repository
public interface MovieRepository extends Neo4jRepository {
Movie findByTitle(@Param("title") String title);
@Query("MATCH (m:Movie) WHERE m.title =~ ('(?i).*'+{title}+'.*') RETURN m")
Collection
findByTitleContaining(@Param("title") String title);
@Query("MATCH (m:Movie)<-[:ACTED_IN]-(a:Person)
RETURN m.title as movie, collect(a.name) as cast LIMIT {limit}")
List
Como você pode, o repositório contém algumas operações personalizadas, bem como as padrão herdadas da classe base.
Em seguida, temos oPersonRepository mais simples, que tem apenas as operações padrão:
@Repository
public interface PersonRepository extends Neo4jRepository {
//
}
Você já deve ter notado quePersonRepository é apenas a interface padrão do Spring Data. Isso ocorre porque, neste exemplo simples, é quase suficiente usar as operações embutidas basicamente porque nosso conjunto de operações está relacionado à entidadeMovie. No entanto, você sempre pode adicionar aqui operações personalizadas que podem envolver operações únicas / múltiplas embutidas.
4.2. Configurando Neo4jRepositories
Como próximo passo, temos que informar ao Spring o repositório relevante, indicando-o na classeNeo4jConfiguration criada na seção 3:
@Configuration
@ComponentScan("com.example.spring.data.neo4j")
@EnableNeo4jRepositories(
basePackages = "com.example.spring.data.neo4j.repository")
public class MovieDatabaseNeo4jConfiguration {
//
}
5. O modelo de dados completo
Já começamos a olhar para o modelo de dados, então vamos agora colocar tudo para fora - osMovie, RoleePerson completos. A entidadePerson faz referência à entidadeMovie por meio do relacionamentoRole.
@NodeEntity
public class Movie {
@Id @GeneratedValue
Long id;
private String title;
private int released;
private String tagline;
@Relationship(type="ACTED_IN", direction = Relationship.INCOMING)
private List roles;
// standard constructor, getters and setters
}
Observe como anotamosMovie com@NodeEntity para indicar que esta classe está diretamente mapeada para um nó no Neo4j.
@JsonIdentityInfo(generator=JSOGGenerator.class)
@NodeEntity
public class Person {
@Id @GeneratedValue
Long id;
private String name;
private int born;
@Relationship(type = "ACTED_IN")
private List movies;
// standard constructor, getters and setters
}
@JsonIdentityInfo(generator=JSOGGenerator.class)
@RelationshipEntity(type = "ACTED_IN")
public class Role {
@Id @GeneratedValue
Long id;
private Collection roles;
@StartNode
private Person person;
@EndNode
private Movie movie;
// standard constructor, getters and setters
}
Claro, essas duas últimas classes são anotadas de forma semelhante e a referência -movies– está ligandoPerson à classeMovie pelo relacionamento “ACTED_IN”.
6. Acesso a dados usando MovieRepository
6.1. Salvar um novo objeto de filme
Vamos salvar alguns dados - primeiro, um novo filme, depois uma pessoa e, é claro, uma função - incluindo todos os dados de relação que temos também:
Movie italianJob = new Movie();
italianJob.setTitle("The Italian Job");
italianJob.setReleased(1999);
movieRepository.save(italianJob);
Person mark = new Person();
mark.setName("Mark Wahlberg");
personRepository.save(mark);
Role charlie = new Role();
charlie.setMovie(italianJob);
charlie.setPerson(mark);
Collection roleNames = new HashSet();
roleNames.add("Charlie Croker");
charlie.setRoles(roleNames);
List roles = new ArrayList();
roles.add(charlie);
italianJob.setRoles(roles);
movieRepository.save(italianJob);
6.2. Recuperando um objeto de filme existente por título
Vamos agora verificar o filme inserido, recuperando-o usando o título definido, que é uma operação personalizada:
Movie result = movieRepository.findByTitle(title);
6.3. Recuperando um objeto de filme existente por uma parte do título
É possível pesquisar para pesquisar um filme existente usando uma parte do título:
Collection result = movieRepository.findByTitleContaining("Italian");
6.4. Recuperando todos os filmes
Todos os filmes podem ser recuperados uma vez e podem ser verificados para a contagem correta:
Collection result = (Collection) movieRepository.findAll();
No entanto, existem vários métodos de busca fornecidos com comportamento padrão que são úteis para os requisitos alfandegários e nem todos são descritos aqui.
6.5. Conte os objetos de filme existentes
Depois de inserir vários objetos de filme, podemos sair da contagem de filmes:
long movieCount = movieRepository.count();
6.6. Excluindo um Filme Existente
movieRepository.delete(movieRepository.findByTitle("The Italian Job"));
Após excluir o filme inserido, podemos procurar o objeto do filme e verificar se o resultado é nulo:
assertNull(movieRepository.findByTitle("The Italian Job"));
6.7. Excluir todos os dados inseridos
É possível excluir todos os elementos no banco de dados, deixando o banco de dados vazio:
movieRepository.deleteAll();
O resultado desta operação remove rapidamente todos os dados de uma tabela.
7. Conclusão
Neste tutorial, examinamos o básico do Spring Data Neo4j usando um exemplo muito simples.
No entanto, o Neo4j é capaz de atender a aplicativos muito avançados e complexos, com um enorme conjunto de relações e redes. E o Spring Data Neo4j também oferece recursos avançados para mapear classes de entidade anotadas para o Neo4j Graph Database.
A implementação dos trechos de código e exemplos acima podem ser encontrados emthe GitHub project - este é um projeto baseado em Maven, portanto, deve ser fácil de importar e executar como está.