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