假設我想透過 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