본문 바로가기

더 나은 엔지니어가 되기 위해/지금은 안쓰는 자바

[스프링 부트 개념과 활용] 데이터 4. Redis, MongoDB, Neo4j

인프런에서 백기선님의 스프링부트 개념과 활용 강의를 듣고, 개인적으로 공부하며 핵심만 정리한 글입니다.

Redis 사용법

1) dependency 추가

pom.xml 에 라이브러리를 추가하자.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2) Redis 띄우기

docker 로 Redis 컨테이너를 띄우자.

$ docker run -p 6379:6379 --name redis_boot -d redis

컨테이너가 만들어졌으면, 다음 명령어로 접속하자.

$ docker exec -i -t redis_boot redis-cli

3) Redis 연동하기

이제 코드 단에서 Redis 에 접근해보자.
바로 실행가능한 코드를 위해 ApplicationRunner 를 사용한다.

@Component
public class RedisRunner implements ApplicationRunner {

  @Autowired
  StringRedisTemplate redisTemplate;

  @Override
  public void run(ApplicationArguments args) throws Exception {
    ValueOperations<String, String> values = redisTemplate.opsForValue();
    values.set("heumsi", "jeon");
    values.set("springboot", "2.3.4");
    values.set("hello", "world");
  }
}

이제 앱을 구동한 뒤, Redis 콘솔로 가서 다음과 같이 확인해보면, Redis 에 정상적으로 값이 들어온 것을 확인할 수 있다.

127.0.0.1:6379> keys *
1) "springboot"
2) "heumsi"
3) "hello"

별다른 설정 없이도 바로 Redis 에 연동된 이유는 스프링 부트의 자동설정이 이미 설정 값들을 다 채워놨기 때문이다. (자동 설정 기본 포트 6379)
그 외 커스텀할 설정 값들은 application.properties 에서 spring.redis. 에 있는 설정값들로 변경할 수 있다.

MongoDB 사용법

1) dependency 추가

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

2) MongoDB 띄우기

도커 컨테이너로 MongoDB 를 띄운다. 포트는 27017 에 맞춰서 연결.

$ docker run -p 27017:27017 --name mongo_boot -d mongo

이후 다음 명령어로 MongoDB 가 돌아가는 컨테이너에 접속하여 몽고 클라이언트 콘솔로 들어간다.

$ docker exec -i -t mongo_boot bash
$ mongo

MongoDB shell version v4.2.3
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("e543b16d-108d-412f-bf63-f315449856b5") }
MongoDB server version: 4.2.3
Welcome to the MongoDB shell.

3) MongoDB 연동하기

마찬가지로 스프링부트가 localhost:27017 로 MongoDB 관련 자동설정을 다 해놓기 때문에, 그냥 바로 사용하면 된다.

먼저 MongoDB 에 들어갈 Collection 을 정의하자.

@Document(collection = "accounts")
public class Account {

  @Id
  private String id;
  private String username;
  private String email;

  ... getter and setter ...
}

이제 DB에 연동하여 연산을 수행해보자. 여기서는 ApplicationRunner 를 Bean 으로 등록하여 이 안에서 사용한다.

3-1) MongoTemplate 사용

jdbcTemplate 처럼 MongoTemplate 이 자동설정에 의해 이미 Bean으로 등록되어있다.

@SpringBootApplication
public class SpringbootmongoApplication {

  @Autowired
  MongoTemplate mongoTemplate;

  public static void main(String[] args) {
    SpringApplication.run(SpringbootmongoApplication.class, args);
  }

  @Bean
  public ApplicationRunner applicationRunner() {
    return args -> {
      Account account = new Account();
      account.setEmail("heumsi@gmail.com");
      account.setUsername("heumsi");

      mongoTemplate.insert(account);
    };
  }
}

어플리케이션을 구동한 뒤, MongoDB 콘솔로 가서 accounts collection 을 확인하면 다음처럼 데이터가 들어간 것을 확인할 수 있다.

> db
test

> use test
switched to db test

> db.accounts.find()
{ "_id" : ObjectId("5e3e5b2782c5961d54f24155"), "username" : "heumsi", "email" : "heumsi@naver.com", "_class" : "me.heumsi.springbootmongo.account.Account" }

3-2) MongoRepository 사용

MongoTemplate 말고도, 다음처럼 MongoRepository 를 상속받아 사용할 수 있다.

public interface AccountRepository extends MongoRepository<Account, String>{
}
@SpringBootApplication
public class SpringbootmongoApplication {

  @Autowired
    AccountRepository accountRepository;

  public static void main(String[] args) {
    SpringApplication.run(SpringbootmongoApplication.class, args);
  }

  @Bean
  public ApplicationRunner applicationRunner() {
    return args -> {
      Account account = new Account();
      account.setEmail("heumsi@gmail.com");
      account.setUsername("heumsi");

      accountRepository.insert(account);
    };
  }
}

4) 테스트 환경

테스트 환경에서의 별도의 테스트용 MongoDB 를 띄울 수가 있다.
이를 위해 먼저 다음 라이브러리를 추가해준다.

<dependency>
  <groupId>de.flapdoodle.embed</groupId>
  <artifactId>de.flapdoodle.embed.mongo</artifactId>
  <scope>test</scope>
</dependency>

다음과 같이 테스트 코드를 짠다.
이 때, @DataMongoTest 를 통해, 데이터 테스트에 필요한 빈들만 로드하게 한다.

@RunWith(SpringRunner.class)
@DataMongoTest
public class AccountRepositoryTest {

  @Autowired
  AccountRepository accountRepository;

  @Test
  public void findByEmail() {
    Account account = new Account();
    account.setUsername("heumsi");
    account.setEmail("heumsi@naver.com");

    accountRepository.save(account);

    Optional<Account> byId = accountRepository.findById(account.getId());
    assertThat(byId).isNotEmpty();
  }
}

테스트를 수행해도, 메인 DB 에 전혀 영향이 가지않는 것을 확인할 수 있다.

Neo4j 사용법

Neo4j 는 그래프 형태의 DB 이다. 이번에는 이 Neo4j 사용법을 알아본다.

1) dependency 추가

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>

2) Neo4j 띄우기

docker 컨테이너로 띄운다.

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

localhost:7687/browser 로 DB 클라이언트에 접속할 수 있다.
기본 계정의 정보는 idneo4j, passwordneo4j 다.

3) Neo4j 연동하기

먼저 Entity 로 사용할 Account 를 다음과 같이 정의한다.
@NodeEntity 가 클래스 앞에 붙는다.

@NodeEntity
public class Account {

  @Id
  @GeneratedValue
  private Long id;

  private String username;
  private String email;

  ... getter and setter ...
}

applicatiom.properties 에는 다음과 같이 설정을 추가한다.

spring.data.neo4j.username = neo4j
spring.data.neo4j.password = neo4j

3-1) SessionFactory 사용

자동설정으로 Bean 등록이 된 SessionFactory 를 이용한다.
Account 에 대한 정보는 이전과 동일함.

@Component
public class Neo4jRunner implements ApplicationRunner {

  @Autowired
  SessionFactory sessionFactory;

  @Override
  public void run(ApplicationArguments args) throws Exception {
    Account account = new Account();
    account.setEmail("heumsi@naver.com");
    account.setUsername("heumsi");

    Session session = sessionFactory.openSession();
    session.save(account);
    sessionFactory.close();
  }
}

3-2) Neo4jRepository 사용

Neo4jRepository 를 구현한 Repository 를 사용해서 연동할 수도 있다

public interface AccountRepository extends Neo4jRepository<Account, Long> {
}
@Component
public class Neo4jRunner implements ApplicationRunner {

  @Autowired
  AccountRepository accountRepository;

  @Override
  public void run(ApplicationArguments args) throws Exception {
    Account account = new Account();
    account.setEmail("siheum@naver.com");
    account.setUsername("siheum");

    accountRepository.save(account);
  }
}

4) Role 사용

Neo4j 는 각 노드에 Role 정보를 담을 수 있다.
먼저 Role 클래스를 정의한다. 이 역시 Entity 이므로 @NodeEntity 가 붙는다.

@NodeEntity
public class Role {

  @Id @GeneratedValue
  private Long id;

  private String name;

  ... getter and setter ...
}

이제 Account 안에 이 Role 을 담는 HashSet 속성을 만들어주자.

@NodeEntity
public class Account {
  ...

  @Relationship(type="has")
  private Set<Role> roles = new HashSet<>();

  ... 
}

이제 다음과 같이 실행단에서 accountrole 을 추가한다.

@Component
public class Neo4jRunner implements ApplicationRunner {

  @Autowired
  AccountRepository accountRepository;

  @Override
  public void run(ApplicationArguments args) throws Exception {
    Account account = new Account();
    account.setEmail("jeon@naver.com");
    account.setUsername("jeon");

    Role role = new Role();
    role.setName("admin");

    account.getRoles().add(role);

    accountRepository.save(account);
  }
}

앱을 구동한 뒤, Neo4j 클라이언트 브라우저를 통해 다음과 같이 데이터가 잘 들어간 것을 확인할 수 있다.