Total Pageviews

2018/09/14

[Neo4j] Using Spring Data to create / delete nodes and relationship

假設我想透過 Spring Data API 建立起以下的 graph:


架構規劃如下:

pom.xml 內容:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>neo4j</groupId>
 <artifactId>springdata</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>springdata</name>
 <url>http://maven.apache.org</url>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <java.version>1.8</java.version>
  <maven.compiler.source>1.8</maven.compiler.source>
  <maven.compiler.target>1.8</maven.compiler.target>
 </properties>

 <dependencies>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-neo4j</artifactId>
   <version>2.0.0.RELEASE</version>
  </dependency>

  <dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <version>1.16.18</version>
  </dependency>

  <dependency>
   <groupId>com.google.guava</groupId>
   <artifactId>guava</artifactId>
   <version>23.0</version>
  </dependency>

  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>3.8.1</version>
   <scope>test</scope>
  </dependency>
 </dependencies>

 <repositories>
  <repository>
   <id>spring-libs-release</id>
   <name>Spring Releases</name>
   <url>https://repo.spring.io/libs-release</url>
   <snapshots>
    <enabled>false</enabled>
   </snapshots>
  </repository>
 </repositories>
</project>

Value objects - Brand
package neo4j.springdata.vo;

import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.ToString;

@NodeEntity
@Data
@ToString
@NoArgsConstructor
@RequiredArgsConstructor
public class Brand {

    @Id
    @GeneratedValue
    private Long id;

    @NonNull
    private String name;

}

Value objects - Product
package neo4j.springdata.vo;

import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.ToString;

@NodeEntity
@Data
@ToString
@NoArgsConstructor
@RequiredArgsConstructor
public class Product {
    
    @Id
    @GeneratedValue
    private Long id;

    @NonNull
    private String name;
    
    @Relationship(type = "MADE_BY")
    private Brand madeBy;
    
}

Repository class - BrandRepository
package neo4j.springdata.repository;

import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import neo4j.springdata.vo.Brand;

@Repository
public interface BrandRepository extends CrudRepository<Brand, Long>{

    @Query("match(b:Brand) where b.name = {name} return b")
    Brand findByName(@Param("name") String name);
    
    @Query("match(n:Brand) optional match (n)-[r]-() delete r, n")
    void deleteAllBrands();
    
}

Repository class - ProductRepository
package neo4j.springdata.repository;

import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import neo4j.springdata.vo.Product;

@Repository
public interface ProductRepository extends CrudRepository<Product, Long> {

    @Query("match (n:Product) optional match (n)-[r]-() delete r, n")
    void deleteAllProducts();
    
}

Service class - BrandService
package neo4j.springdata.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import neo4j.springdata.repository.BrandRepository;
import neo4j.springdata.vo.Brand;

@Service
public class BrandService {

    @Autowired
    private BrandRepository brandRepo;
    
    public void createBrands(List<Brand> brands) {
        brandRepo.saveAll(brands);
    }
    
    public void deleteAllBrands() {
        brandRepo.deleteAllBrands();
    }

}

Service class - ProductService
package neo4j.springdata.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import neo4j.springdata.repository.BrandRepository;
import neo4j.springdata.repository.ProductRepository;
import neo4j.springdata.vo.Brand;
import neo4j.springdata.vo.Product;

@Service
public class ProductService {

    @Autowired
    private BrandRepository brandRepo;
    
    @Autowired
    private ProductRepository productRepo;
    
    public void createProducts(List<Product> products, String brandName) {
        Brand brand = brandRepo.findByName(brandName);
        products.forEach(p -> p.setMadeBy(brand));
        
        productRepo.saveAll(products);
    }
    
    public void deleteAllProducts() {
        productRepo.deleteAllProducts();
    }
    
}

Client class - App
package neo4j.springdata;

import java.util.List;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;

import com.google.common.collect.Lists;

import neo4j.springdata.service.BrandService;
import neo4j.springdata.service.ProductService;
import neo4j.springdata.vo.Brand;
import neo4j.springdata.vo.Product;

@SpringBootApplication
@EnableNeo4jRepositories
public class App {

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }

    @Bean
    CommandLineRunner createBrands(BrandService brandService) {
        return args -> {
            List<Brand> brands = Lists.newArrayList(new Brand("Apple"), new Brand("Google"), new Brand("Samsung"));
            brandService.createBrands(brands);
        };
    }

    @Bean
    CommandLineRunner createProducts(ProductService productService) {
        return args -> {
            List<Product> appleProducts = Lists.newArrayList(new Product("iPhne"), new Product("iPad"),
                    new Product("iPad Pro"), new Product("MacBook"), new Product("MackBook Pro"));
            productService.createProducts(appleProducts, "Apple");

            List<Product> googleProducts = Lists.newArrayList(new Product("Nexus 6P"), new Product("Nexus 5X"),
                    new Product("Chromecast"));
            productService.createProducts(googleProducts, "Google");

            List<Product> samsungProducts = Lists.newArrayList(new Product("Samsung Galaxy Note 8"),
                    new Product("Samsung Galaxy Note FE"), new Product("Samsung Galaxy S9"),
                    new Product("Samsung Galaxy A8"));
            productService.createProducts(samsungProducts, "Samsung");
        };
    }

    @Bean
    CommandLineRunner deleteProductAndBrands(BrandService brandService, ProductService productService) {
        return args -> {
            brandService.deleteAllBrands();
            productService.deleteAllProducts();
        };
    }

}


application.properties (記錄連線資訊)
spring.data.neo4j.uri=bolt://localhost
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=secret


1 comment:

Data Annotation said...

Thank you for sharing this useful information with us. Did you know data annotationholds the key to successful machine learning models? It’s a vital task that bridges the gap between raw data and AI comprehension. What exactly is data annotation, you ask? Well, it’s the process of labeling data to train algorithms. But why is it so crucial? Simply put, it’s the foundation on which machine learning thrives.