안녕하세요.

오늘은 MongoDB 데이터를 메서드로 주입하는 방법에 대해 포스팅 합니다.

노말한 방법은 MongoDB 데이터를 클래스 필드 이름이랑 매칭 시켜 주입합니다.

노말한 방법은 이전 포스팅을 참고해주세요!

SpringBoot와 MongoDB 연동하기

그런데, 만약 MongoDB데이터의 키 값과 클래스 필드 이름 매칭이 아닌, 클래스 필드 이름은 자유롭게 사용하고 싶을때는 어떻게 해야 할까요? 또는 데이터를 가공해서 넣고 싶을 때는 어떻게 해야 할까요?

즉 이번 포스팅은 MongoDB데이터를 먼저 받고 처리 하는것이 아닌 MongoDB 데이터를 받는 시점에서 처리하는 방법에 관한 것입니다.

@Field Annotation API 사용하기

위에서 언급한데로, 만약 MongoDB데이터의 키 값과 클래스 필드의 이름을 따로 사용하고 싶다면, @Field API를 사용하면 됩니다.

예를들어, MongoDB에 아래와 같은 Document를 가지는 Person Collection이 있다고 가정합니다.

{
   "name": "Mommoo",
   "job": "developer"
}

이 데이터를 주입 받는 Person 클래스를 아래와 같이 만들었다고 가정합니다.

@Document(collection="person")
public class Person {
   private String name;
   private String job;
}

위와 같은 상황이라면, 문제 없이 데이터를 주입 받습니다.

하지만 만약, Person의 멤버변수 namedeveloperName으로 바꾸고 싶다면 아래와 같이 @Filed API를 사용합니다.

@Document(collection="person")
public class Person {
   @Field("name")
   private String developerName;
   private String job;
}

@Field Annotation API를 이용하여 데이터 주입 메서드 만들기

문제상황 설정

Person Collection 정보를 위와 같이 따로 받지 않고, 아래의 NameCard 클래스로 받고 싶다면 어떻게 해야 할까요?

public class NameCard {
   private String developerName;
   priavte String job;
}

당연히 이런건, Person Collection에 NameCard 키를 추가 한 후 거기에 name과 job을 넣어 구조를 맞추는 경우가 많지만...

노말한 방법중 하나는 위의 Person 클래스로 데이터를 받고, NameCard를 뒤늦게 만드는 방법 입니다.

아래의 예시 처럼요.

@Document(collection="person")
@Getter //lombok 라이브러리 getter를 자동으로 만들어 줍니다.
public class Person {
   private String name;
   private String job;
}

public class Person2 {
   private NameCard nameCard;
   
   public Person2(NameCard nameCard){
       this.nameCard = nameCard;
  }
}

//Person을 주입 받은 어떤 메서드가 있다고 가정합니다.
public Person2 convertPersonToPerson2(Person p) {
  NameCard nameCard = new NameCard(p.getName(), p.getJob());
  return new Person2(nameCard);
}

해당 예시의 특징은 persistence class (Person)domain class(Person2)를 나누어서 사용하는 것을 알 수 있습니다. 즉, PersonDTO역할을 하며, Person2business logic역할을 합니다.

하지만, Spring이 추구하는 프로그래밍 패러다임중 하나인 POJO를 이루고자 한다면, 그렇게 좋은 구조는 아닌거 같습니다.

Plain Old Java Object : 그냥, 평범한 객체 오브젝트를 뜻합니다.

객체를 Data Holder로만 사용하면 도메인 영역을 처리하기 어려우니,

기존의 객체지향 방식으로 데이터 와 관련있는 기능들을 클래스에 넣음으로써, 도메인 영역을 더 효율적으로 처리하자는 의미입니다.

POJO방식으로 처리

위에서 언급한 DTObusiness logic을 한곳에서 처리 하기 위해서는 데이터 주입을 원하는 곳으로 받고 처리할 수 있어야 합니다.

아래와 같이 데이터 주입을 메서드로 받음으로써, 처리 할 수 있습니다.

public class Person {
  private NameCard nameCard = new NameCard();
 
  @AccessType(AccessType.Type.PROPERTY)
  @Field("name")
  public setName(String name) {
      nameCard.setDeveloperName(name);
  }
 
  @AccessType(AccessType.Type.PROPERTY)
  @Field("job")
  public setName(String job) {
      nameCard.setJob(job);
  }
}

마무리

생성자로 데이터를 주입받는 방법도 있지만, 해당 방법은 데이터에 대응하는 필드가 반드시 존재 해야 합니다. 그렇기에 위와 같이 필드가 아예 다를 때는 메서드로 주입 받아야 합니다.

주입받는 메서드의 접근 제어자는 무조건 public이어야 합니다. 그렇지 않으면 런타임 에러가 발생합니다.

Jackson 라이브러리를 사용 하신다면, 해당 setter 메서드 때문에 원하지 않게 JSON 구조로 잡힐때가 있습니다. 그럴 경우에는 아래와 같이 @JsonIgnore API를 사용하시면 됩니다.

public class Person {
   
   @JsonIgnore
   @AccessType(AccessType.Type.PROPERTY)
   @Field("name)
   public setName(String name) {
      ...
  }
}


포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee



안녕하세요 오늘 포스팅은 SpringBoot와 MongoDB를 연동 방법입니다.


저는 최소한의 설정만을 원칙으로 하기 때문에, 연동에 필요한 부분만 알려드리고자 합니다.


SpringBoot 프레임워크가 이미 구현 해 놓은 API가 있어서 정말 간단합니다.


주의!!

해당 포스팅은 MongoDB Server 다운로드, MongoDB 개념, 사용법 등을 설명하지 않습니다.



SpringBoot 환경과 MongoDB 환경 정보


SpringBoot는 패키지 매니저로 Gradle(4.8.1)을 사용하구요, 

SpringBoot 프레임워크 버전은 2.1.0.RELEASE 입니다.

MongoDB는 윈도우10 x64 전용으로 4.0.4 버전입니다.



SpringBoot 설정


먼저 SpringBoot 프로젝트에 필요한 의존 라이브러리를 build.gradle 파일의 dependencies에 아래와 같이 추가합니다.


버전을 따로 기입 안함으로써, 2.1.0.RELEASE 버전이 제시하는 Default 버전의 라이브러리가 의존됩니다.


dependencies {

...
implementation('org.springframework.boot:spring-boot-starter-data-mongodb')
...
}


그다음, application.properties 파일에 MongoDB 정보를 아래와 같이 기입해야 합니다.


application.properties 파일은 보통 프로젝트/src/main/resource 경로에 있습니다.


spring.data.mongodb.uri=mongodb://[ip 정보]:[port 정보]
spring.data.mongodb.database=[데이터베이스 이름]


몽고 DB의 기본 정보는 localhost(127.0.0.1) ip와 27017 포트 구성을 가집니다.


MongoDB Server에 Database를 만드셨다면, 몽고 DB의 URI 예시는 다음과 같습니다.


mongodb://127.0.0.1:27017/MyDatabase


저는 데이터베이스 이름을 따로 설정했는데요, 아래와 같이 uri 정보에 한번에 기입할 수도 있습니다.


spring.data.mongodb.uri=mongodb://[ip 정보]:[port 정보]/[데이터베이스 이름]


해당 정보는 자바 파일로도 작성 가능합니다.

@Configuration
public class MongoDBConfiguration extends AbstractMongoConfiguration {
@Override
public MongoClient mongoClient() {
return new MongoClient("ip 정보", 포트정보);
}

@Override
protected String getDatabaseName() {
return "데이터베이스 이름";
}
}


MongoDB에 Document에 대응하는 DTO 클래스 만들기.


MongoDB Document가 아래와 같은 구조라 가정한다면,


Person Document


1
2
3
4
{
    "name""Mommoo",
    "job""Developer"
}
cs


DTO Class는 다음과 같이 작성됩니다.


Person.java


1
2
3
4
5
6
7
8
9
public class Person {
    private String name;
    private String job;
 
    @Override
    public String toString() {
        return "name is " + name + " job is " + job;
    }
}
cs


주의!!


보통은 Document 어노테이션을 통해, class와 매치되는 Collection을 맵핑 해주어야 합니다.

ex) @Document(collection="myCollection")


Document에 들어있는 모든 필드를 기입했다면, Document 어노테이션을 적지 않아도 됩니다만,

만약 필요한 필드만 기입하면 Document 어노테이션을 반드시 기술 해주어야 합니다.


DTO 클래스에 DB 데이터를 넣어 줄 Repository 객체 작성하기.


정말 간단하게, 아래와 같이 코딩하면 됩니다. 


특징으로는, MongoRepository 제네릭 부분에 앞서 작성한 DTO Class를 입력하면 됩니다. ( 예시로는 Person )


PersonMongoDBRepository.java


1
2
3
public interface PersonMongoDBRepository extends MongoRepository<Person, String> {
 
}
cs


몇몇 분들은 JPA 방식이라는 것을 눈치채셨을 겁니다. 


MongoDB의 Document 데이터를 호출하는 메서드는 기본적으로 MongoRepository에 이미 기술 되어 있습니다.


MongoDB의 쿼리랑 대응되는 메서드가 기본으로 존재합니다.

(findAll, insert 등등)


SQL문에 Where 조건절에 대응되는 쿼리를 작성하고 싶다면, MongoDB의 Query대로 method를 작성하면 됩니다.

예를들어, name 필드값 기준인 Document만 호출하고 싶다면 아래와 같이 작성됩니다.


findBy + 필드이름


1
2
3
public interface PersonMongoDBRepository extends MongoRepository<Person, String> {
    public Person findByName(String name);
}
cs


더 자세한 쿼리 예시를 보고 싶다면 아래의 사이트의 6.3 Query Methods 부분을 참고해주세요.

https://docs.spring.io/spring-data/mongodb/docs/1.2.0.RELEASE/reference/html/mongo.repositories.html



테스트 해보기.


아래와 같이 테스트 코드를 작성해서 호출한 데이터가 출력되는지 확인합니다.


SpringBootMongoDBTest.java


1
2
3
4
5
6
7
8
9
10
11
@RunWith(SpringRunner.class)
@SpringBootTest()
public class SpringBootMongoDBTest {
    @Autowired()
    private ProjectMongoDBRepository projectMongoDBRepository;
 
    @Test
    public void printProjectData() {
        System.out.println(projectMongoDBRepository.findAll());
    }
}
cs


저는 프로젝트/src/test/java/패키지 안에다가 테스트 class를 만들어 실행했습니다.



지금까지, MongoDB 연동 방법에 대해 알아봤습니다.


제가 소개한 방법은 MongoDB의 특징인 Query 조회와 비슷하게 접근 할 수 있는 방법입니다.

(JPA 방법이죠)


기존 MySQL와 같은 관계형 데이터베이스 방법대로 SQL문으로 조회하는 방법도 있습니다.

구글에 mongoDB template로 검색해보세요.


읽어주셔서 감사합니다.


포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

+ Recent posts