ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [30] 스프링 데이터: NoSQL - Neo4j
    Spring/Spring boot 2020. 9. 8. 08:58
    반응형

    Neo4j는 node 간의 연관관계(친구의 친구의 친구를 조회하는 등과 같은 작업)를 표현하는 데 있어서 풍부한 기능을 지원하는 graph DB입니다.

     

    spring boot에서 Neo4j를 사용하기 위한 의존성을 추가하기 위해 pom.xml에 다음의 내용을 추가합니다.

    <dependencies>
    
    	...
        
        <dependency>
        	<groupId>org.springframework.boot</groupId>
            <artfactId>spring-boot-starter-data-neo4j</artifactId>
        </dependecy>
        
        ...
        
    </depencencies>

    Neo4j는 하위 호환성이 떨어집니다. 과거 버전에서 지원되던 class가 없어진 것들이 많습니다. 기존에 Neo4j 구버전을 사용하던 중이였다면 버전 변경 시 발생할 수 있는 영향을 고려하여 변경해야 합니다.

     

     

    docker에서 Neo4j 컨테이너를 생성함과 동시에 실행해줍니다.

    docker run -p 7474:7474 -p 7687:7687 -d --name neo4j_boot neo4j

    port를 두 개 지정하고 있는데, 7474는 http, 7687은 bolt protocol 통신 용도로 각각 사용하게 됩니다.

    이후 http://localhost:7474/browser 로 접속하면 다음과 같은 브라우저 화면을 볼 수 있습니다.

    이 browser 내에서 학습도 가능합니다.

    Username과 Password에 neo4j를 입력하고 Connect 버튼을 클릭하면 로그인되면서 password를 변경하게 됩니다. 기억하기 좋은 password로 변경해주세요.

     

    password 변경이 완료되면 다음과 같은 화면을 볼 수 있습니다.

     

    neo4j의 password를 변경했기 때문에 spring boot의 설정 파일에 password를 명기해야 합니다. application.properties 파일을 열어 다음의 내용을 추가해줍니다.

    spring.data.neo4j.password= #변경한 패스워드를 입력해 주세요.
    spring.data.neo4j.username=neo4j

     

    neo4j에 graph를 저장하는 방법은 크게 두 가지가 있습니다. 하나는 SessionFactory를 사용하는 것이고 다른 하나는 Neo4jRepository<T, ID> interface를 상속받은 repository interface를 사용하는 것입니다.

     

    account 패키지를 생성 후 Account class와 Role class 그리고 AccountRepository interface를 생성합니다.

    Account class의 코드는 다음과 같습니다.

    package me.dave.account;
    
    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 java.util.HashSet;
    import java.util.Set;
    
    @NodeEntity	//	①
    public class Account {
    
        @Id @GeneratedValue //	②
        private Long id;
    
        private String username;
    
        private String email;
    
        @Relationship(type = "has")	//	③
        private Set<Role> roles = new HashSet<>();	//	④
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    
        public Set<Role> getRoles() {
            return roles;
        }
    
        public void setRoles(Set<Role> roles) {
            this.roles = roles;
        }
    }
    

    ① 이 class가 neo4j graph의 node를 정의하는 class임을 나타냅니다.

    ② neo4j에서 id는 숫자 타입만 사용할 수 있습니다. @GeneratedValue를 사용하여 자동 생성되는 값임을 지정합니다.

    ③ 다른 node와의 연관관계를 설정합니다. 여기서는 "has"라는 타입으로 엣지를 정의합니다.

    ④ 관계는 집합 형태로 정의하게 됩니다. 따라서 Set <Type> 형으로 나타내며 null을 인정하지 않으므로 HashSet<> 타입으로 초기화합니다.

     

    Role class의 코드입니다.

    package me.dave.account;
    
    import org.neo4j.ogm.annotation.GeneratedValue;
    import org.neo4j.ogm.annotation.Id;
    import org.neo4j.ogm.annotation.NodeEntity;
    
    @NodeEntity
    public class Role {
    
        @Id @GeneratedValue
        private Long id;
    
        private String roleName;
    
        public String getRoleName() {
            return roleName;
        }
    
        public void setRoleName(String roleName) {
            this.roleName = roleName;
        }
    }
    

     

    AccountRepository interface의 코드는 다음과 같습니다.

    package me.dave.account;
    
    import org.springframework.boot.ApplicationRunner;
    import org.springframework.data.neo4j.repository.Neo4jRepository;
    
    public interface AccountRepository extends Neo4jRepository<Account, Long> {
    }
    

     

    이제 테스트를 위한 Runner class를 하나 작성합니다.

    package me.dave;
    
    import me.dave.account.Account;
    import me.dave.account.AccountRepository;
    import me.dave.account.Role;
    import me.dave.account.RoleRepository;
    import org.neo4j.ogm.session.Session;
    import org.neo4j.ogm.session.SessionFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.ApplicationArguments;
    import org.springframework.boot.ApplicationRunner;
    import org.springframework.stereotype.Component;
    
    @Component
    public class Neo4jRunner implements ApplicationRunner {
    
        @Autowired
        SessionFactory sessionFactory;	//	①
    
        @Autowired
        AccountRepository accountRepository;	//	②
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            //1.SessionFactory를 통해 neo4j를 사용.
            Account account1 = new Account();
            account1.setUsername("Dave");
            account1.setEmail("dave@gmail.com");
    
            Role role1 = new Role();
            role1.setRoleName("admin");
            account1.getRoles().add(role1);
    
            Session session = sessionFactory.openSession();	//	③
            session.save(account1);	//	④
            sessionFactory.close();	//	⑤
    
            //2.Repository를 통해 neo4j를 사용.
            Account account2 = new Account();
            account2.setUsername("Camel");
            account2.setEmail("camel@naver.com");
    
            Role role2 = new Role();
            role2.setRoleName("user");
            account2.getRoles().add(role2);
    
            accountRepository.save(account2);	//	⑥
    
            System.out.println("Process was finished");
        }
    }
    

    ① neo4j를 사용하기 위해 SessionFactory bean을 주입받습니다.

    neo4j를 사용하기 위해 Neo4jRepository<T, ID> 타입의 bean을 주입받습니다.

     SessionFactory.openSession()으로 세션 객체를 받아와서

     세션 객체의 save()를 사용하여 neo4j에 graph를 저장합니다. 

    SessionFactory.close()로 세션을 닫아줘야 application을 종료할 수 있습니다.

    Neo4jRepository의 save를 통해 node를 저장합니다. (개인적으로 이쪽이 사용하기 편하고 직관적이라 추천합니다.)

     

     

    위의 코드를 실행하고 neo4j browser를 통해 다음과 같이  graph를 살펴볼 수 있습니다.

    좌측의  DB 모양 아이콘을 클릭하고 Node Labels에서 조회하기 원하는 Label을 선택합니다. 해당되는 graph가 보기 좋게 조회되는 것으로 보아 성공적으로 insert 된 거 같습니다.

     

    위에 해당되는 소스코드는 github.com/camel-master/Neo4jExample.git 에서 받아볼 수 있습니다.

    댓글

Designed by Tistory.