Neo4j系列-整合SpringBoot


. 開發環境

  • Springboot 1.5.9.RELEASE(Springboot-parent2.0 版本里面接口變化較大,后期會出一個2.0版本的)
  • jdk1.8
    springboot pom配置如下
    <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath /> </parent> 

neo4j 相關配置如下

<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <neo4j-ogm.version>2.1.3</neo4j-ogm.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-neo4j</artifactId> </dependency> <!--<dependency> <groupId>org.neo4j</groupId> <artifactId>neo4j-ogm-bolt-driver</artifactId> <version>${neo4j-ogm.version}</version> </dependency>--> </dependencies> 

說明:neo4j-ogm-bolt-driver是二進制驅動,本文列出了這種高性能的驅動但是沒有使用,spring-data-neo4j支持多種bolt,http(s)倆種協議操作。默認使用http(s)協議驅動,如下圖

 
對http(s)的支持

補充:

若想使用嵌入式的Neo4j驅動,可以引入如下jar包:

        <dependency> <groupId>org.neo4j</groupId> <artifactId>neo4j-ogm-embedded-driver</artifactId> <version>${neo4j-ogm.version}</version> </dependency> 

2. 項目創建

pom完整配置如下:

<?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>io.fredia</groupId> <version>1.0.0-SNAPSHOT</version> <artifactId>femicro-graph</artifactId> <name>femicro-graph</name> <url>http://maven.apache.org</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath /> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <neo4j-ogm.version>2.1.3</neo4j-ogm.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-neo4j</artifactId> </dependency> <!--<dependency> <groupId>org.neo4j</groupId> <artifactId>neo4j-ogm-bolt-driver</artifactId> <version>${neo4j-ogm.version}</version> </dependency>--> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 
 
忽略dockerfile和static目錄

3. 配置application.properties

server.port=12012 spring.data.neo4j.username=neo4j spring.data.neo4j.password=123 spring.data.neo4j.uri=http://127.0.0.1:7474 

4. 創建節點類(NodeEntity)

package io.fredia.femicro.graph.entity; import org.neo4j.ogm.annotation.GraphId; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Property; @NodeEntity(label = "User") public class UserNode { @GraphId private Long nodeId; @Property(name = "userId") private String userId; @Property(name = "name") private String name; @Property(name = "age") private int age; public Long getNodeId() { return nodeId; } public void setNodeId(Long nodeId) { this.nodeId = nodeId; } public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } 

注解解析:

@NodeEntity:聲明該類為Neo4j的節點類

多看源碼

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Inherited public @interface NodeEntity { String CLASS = "org.neo4j.ogm.annotation.NodeEntity"; String LABEL = "label"; String label() default ""; } 

@GraphId:Neo4j的主鍵id,必須為長整型
@Property:Neo4j的節點屬性值,支持8種基本類型外加String

5. 創建repositories類(封裝過的dao)

package io.fredia.femicro.graph.repository; import java.util.List; import org.springframework.data.neo4j.annotation.Query; import org.springframework.data.neo4j.repository.GraphRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Component; import io.fredia.femicro.graph.entity.UserNode; @Component public interface UserRepository extends GraphRepository<UserNode> { @Query("MATCH (n:User) RETURN n ") List<UserNode> getUserNodeList(); @Query("create (n:User{age:{age},name:{name}}) RETURN n ") List<UserNode> addUserNodeList(@Param("name") String name, @Param("age")int age); } 

源碼解析:GraphRepository.class

public interface GraphRepository<T> extends Neo4jRepository<T, Long> { <S extends T> S save(S s, int depth); <S extends T> Iterable<S> save(Iterable<S> entities, int depth); T findOne(Long id, int depth); Iterable<T> findAll(); Iterable<T> findAll(int depth); Iterable<T> findAll(Sort sort); Iterable<T> findAll(Sort sort, int depth); Iterable<T> findAll(Iterable<Long> ids); Iterable<T> findAll(Iterable<Long> ids, int depth); Iterable<T> findAll(Iterable<Long> ids, Sort sort); Iterable<T> findAll(Iterable<Long> ids, Sort sort, int depth); /** * Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object. * {@link Page#getTotalPages()} returns an estimation of the total number of pages and should not be relied upon for accuracy. * * @param pageable * @return a page of entities */ Page<T> findAll(Pageable pageable); /** * Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object. * {@link Page#getTotalPages()} returns an estimation of the total number of pages and should not be relied upon for accuracy. * * @param pageable * @param depth * @return a page of entities */ Page<T> findAll(Pageable pageable, int depth); } 
注意:高版本已經移除該類
 
5.0.5REALSE

在把這個類的結構圖列出:


 
樹狀圖

不難發現,GraphRepository已經經過多層封裝,包含了實現了crud基本功能外,再集成了分頁功能,之后提煉了常用查詢的方法,提高了代碼復用性。

5. 創建Neo4jConfig配置

最簡單的配置如下

package io.fredia.femicro.graph.config; import org.springframework.context.annotation.Configuration; import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableNeo4jRepositories(basePackages = "io.fredia.femicro.graph.repository") @EnableTransactionManagement // 激活SDN隱式事務 public class Neo4jConfig { } 
注意:此處每個spring-data-neo4j的版本變動都很大,所以此處的配置非常繁雜。請根據具體應用jar版本區別。

此處為spring-data-neo4j 4.2.9RELEASE版本:


 
4.2.9RELEASE

此處為spring-data-neo4j 5.0.5REALSE版本如下:


 
5.0.5REALSE
此處坑很多,使用Springcloud的同學小心版本問題,目測網上可參考的教程較少,可過段時間后采用新版本。
注解解析:

@Configuration:springboot聲明配置類,一般為單例模式
@EnableNeo4jRepositories:Neo4j掃描Repositories所在包,理解為mybatis掃描mapper
@EnableTransactionManagement:Neo4j完整的支持ACID,所以此處開啟事務功能。

6. 編寫Service類

package io.fredia.femicro.graph.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import io.fredia.femicro.graph.entity.UserNode; import io.fredia.femicro.graph.repository.UserRelationRepository; import io.fredia.femicro.graph.repository.UserRepository; @Service public class Neo4jService { @Autowired private UserRepository userRepository; @Autowired private UserRelationRepository userRelationRepository; public int addUser(UserNode userNode) { userRepository.addUserNodeList(userNode.getName(), userNode.getAge()); return 1; } public List<UserNode> getUserNodeList() { return userRepository.getUserNodeList(); } } 

7. 編寫Controller類

package io.fredia.femicro.graph.controller; import java.util.List; import java.util.UUID; import org.apache.commons.lang3.RandomUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import io.fredia.femicro.graph.entity.UserNode; import io.fredia.femicro.graph.service.Neo4jService; @RestController public class Neo4jController { @Autowired private Neo4jService Neo4jService; //創建400個node @RequestMapping(path = "/addUserNode", method = RequestMethod.GET) public String addUserNode() { int i = 0; do { UserNode user = new UserNode(); user.setAge(RandomUtils.nextInt(15, 40)); user.setName("Fredia" + RandomUtils.nextInt(1, 1000)); user.setUserId(UUID.randomUUID().toString()); user.setNodeId(RandomUtils.nextLong(1L, 999L)); Neo4jService.addUser(user); i += 1; } while (i < 400); return "ok"; } @RequestMapping(path = "/getUserNodeList", method = RequestMethod.GET) public List<UserNode> getUserNodeList() { return Neo4jService.getUserNodeList(); } } 

8. 測試結果

啟動項目后,本地請求

http://localhost:12012/addUserNode 
 
控制台響應

查看數據庫內容:


 
已經完成

發現id屬性為自動生成,和數據庫主鍵一樣。


 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM