Quantcast
Channel: CodeSection,代码区,数据库(综合) - CodeSec
Viewing all articles
Browse latest Browse all 6262

Neo4j学习笔记九【Spring Data Neo4j】

$
0
0

到目前为止,我们一直在直接使用Neo4j提供的核心Api爱来访问数据库,尽管这种方法的功能强大且极其灵活,但是底层Neo4j Api的操作有时非常繁琐。下面我们学习下Spring Data Neo4j(SDN),这是一个以更简单、更熟悉为目标的基于Spring开发模型的Spring Data项目中的子项目。

SDN适合做什么以及不适合做什么

SDN从本质上给需要或期待操作基于POJO的域实体的开发者提供了一种方便的使用代码或库函数的方法。如果是早已使用Spring,或早已经在使用丰富领域模型并想映射到一个图形数据库,SDN正适合做这样的工作。

SDN不适合一次处理任意类型的大量数据场景。要加载或存储的任何逻辑在一次操作中超过10000个单元对SDN来说不是一个好的选择。另外,通过提供一个间接层,SDN会比仅仅使用核心Api慢,因此,如果速度和性能时考虑的最重要因素的话,最好还是使用其本身的Api。SDN提供了访问底层GraphDatabaseService实例的代码,可以使用底层核心Api来获得最佳的性能和最大的灵活性。

搭建环境

查看 Spring Boot官网 ,目前最新版1.4(SNAPSHOP)已经包含了Neo4j,但是我们还是使用最新的RELEASE版1.3.6。SDN使用最新版的4.1.2.RELEASE。

1、新建maven项目,pom文件中引入Spring Boot 1.3.6.RELEASE,Spring Boot这里就不多说了,基本上Java码农标配。 2、添加spring-data-neo4j 4.1.2.RELEASE的依赖

下面列出pom文件内容

<?xml version="1.0" encoding="UTF-8"?> <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>cn.didadu</groupId> <artifactId>springboot_sdn</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.6.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <lombok.version>1.16.2</lombok.version> <spring-data-neo4j.version>4.1.2.RELEASE</spring-data-neo4j.version> <guava.version>19.0</guava.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId></dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- spring-data-commons版本有冲突,要升级 --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-neo4j</artifactId> <version>${spring-data-neo4j.version}</version> <exclusions> <exclusion> <artifactId>spring-data-commons</artifactId> <groupId>org.springframework.data</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-commons</artifactId> <version>1.12.2.RELEASE</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>${guava.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 3、配置spring-data-neo4j /** * 新建类Neo4jConfig,用于初始化Neo4j连接 */ packagecn.didadu.config; @Configuration //启动类的@SpringBootApplication会自动扫描同级包以及子包,所以下面的@ComponentScan不加应该没关系 //@ComponentScan("cn.didadu.sdn") @EnableNeo4jRepositories("cn.didadu.sdn.repository") @EnableTransactionManagement publicclassNeo4jConfigextendsNeo4jConfiguration{ @Bean publicorg.neo4j.ogm.config.ConfigurationgetConfiguration(){ org.neo4j.ogm.config.Configuration config = neworg.neo4j.ogm.config.Configuration(); config.driverConfiguration() .setDriverClassName("org.neo4j.ogm.drivers.http.driver.HttpDriver") .setURI("http://neo4j:zhangjing@localhost:7474"); returnconfig; } @Override publicSessionFactorygetSessionFactory(){ /** * 如果不指定节点映射的java bean路径,保存时会报如下警告,导致无法将节点插入Neo4j中 * ... is not an instance of a persistable class */ returnnewSessionFactory(getConfiguration(),"cn.didadu.sdn.entity"); } } SDN建模

下面我们使用SDN来构造和第二章一模一样的数据

#### 1、新建Java Bean与节点映射 ```java package cn.didadu.sdn.entity; @Data @NodeEntity(label="USERS") public class User { public User(){} public User(String name){ this.name = name; } @GraphId private Long nodeId; @Property(name="name") private String name; //关系直接定义在节点中 @Relationship(type = "IS_FRIEND_OF", direction=Relationship.OUTGOING) private List<User> friends; //使用外部定义的关系 @Relationship(type = "HAS_SEEN") private List<Seen> hasSeenMovies; } @Data @NodeEntity(label = "MOVIES") public class Movie { public Movie(String name){ this.name = name; } @GraphId private Long nodeId; @Property(name="name") private String name; } @Data @RelationshipEntity(type="HAS_SEEN") public class Seen { public Seen(Integer stars, User startNode, Movie endNode){ this.stars = stars; this.startNode = startNode; this.endNode = endNode; } @GraphId private Long id; @Property private Integer stars; @StartNode private User startNode; @EndNode private Movie endNode; } 2、新建Java Bean对应的Repository类 packagecn.didadu.sdn.repository; @Repository publicinterfaceUserRepositoryextendsGraphRepository<User>{ @Query("MATCH (user:USERS {name:{name}}) RETURN user") User getUserByName(@Param("name")String name); } @Repository publicinterfaceMovieRepositoryextendsGraphRepository<Movie>{ } @Repository publicinterfaceSeenRepositoryextendsGraphRepository<Seen>{ } 访问和持久化实体 1、编写业务Service类 packagecn.didadu.service; @Service publicclassUserService{ @Autowired privateUserRepository userRepository; @Autowired privateMovieRepository movieRepository; @Autowired privateSeenRepository seenRepository; @Transactional publicvoidinitData(){ /** * 初始化用户 */ User user1 = newUser("John Johnson"); User user2 = newUser("Kate Smith"); User user3 = newUser("Jack Jeffries"); /** * 为用户John添加朋友关系 */ user1.setFriends(Lists.newArrayList(user2, user3)); /** * 初始化电影 */ Movie movie1 = newMovie("Fargo"); Movie movie2 = newMovie("Alien"); Movie movie3 = newMovie("Heat"); /** * 初始化HAS_SEEN关系 */ Seen hasSeen1 = newSeen(5, user1, movie1); Seen hasSeen2 = newSeen(3, user2, movie3); Seen hasSeen3 = newSeen(6, user2, movie2); Seen hasSeen4 = newSeen(4, user3, movie1); Seen hasSeen5 = newSeen(5, user3, movie2); /** * 如果不加@Transactional,下面每个save都会单独开启事物 */ userRepository.save(Lists.newArrayList(user1, user2, user3)); movieRepository.save(Lists.newArrayList(movie1, movie2, movie3)); seenRepository.save(Lists.newArrayList(hasSeen1, hasSeen2, hasSeen3, hasSeen4, hasSeen5)); } @Transactional publicUsergetUserByName(String name){ returnuserRepository.getUserByName(name); } } 1、编写Unit Test //测试前先删除数据 match (user:USERS),(movie:MOVIES) detach delete user,movie; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = SpringbootSdnApplication.class) publicclassUserServiceTest{ @Autowired privateUserService userService; /** * 因为是通过http连接到Neo4j数据库的,所以要预先启动Neo4j:neo4j console */ @Test publicvoidtestInitData(){ userService.initData(); } @Test publicvoidtestGetUserByName(){ User user = userService.getUserByName("John Johnson"); System.out.println(user); } }

至此我们已经可以通过SDN来操作Neo4j了,在本章节之前都是通过嵌入式的方式访问Neo4j的,只有这一章是通过HTTP访问Neo4j。在本节开头说过SDN提供了访问底层GraphDatabaseService实例的代码,但事实上当前版本的SDN中已经没有GraphDatabaseService相关类了,所以目前看来只能通过HTTP的方式远程访问Neo4j数据库了。什么。。。那么强大的核心api用不了了?这怎么能忍!


Viewing all articles
Browse latest Browse all 6262

Trending Articles