blog
[SpringBoot/AWS EC2] MongoDB - 1 (Auto-Generated Field) 본문
[SpringBoot/AWS EC2] MongoDB - 1 (Auto-Generated Field)
hjkongkong 2021. 12. 8. 23:41본격적으로 개발을 앞서 오늘 사용 할 환경정보이다.
JAVA 1.8
springBoot 2.1.9.RELEASE
gradle 7.1
spring data jpa 2.4.5 // 주석처리
mongodb version v3.6.3
딱히 명시를 안한 의존성들은 springboot 2.1.9의 default 버전을 사용한다.
게시판의 요구사항은 다음과 같다.
게시판 기능 | 회원 기능 |
게시글 조회 | 구글/네이버 로그인 |
게시글 등록 | 로그인 한 사용자 글 작성 권한 |
게시글 수정 | 본인 작성 글에 대한 관리 |
게시글 삭제 |
gradle의 의존성을 주입한다.
gradle dependencies는 아래의 사이트에서 검색해서 사용자가 많은 버전 골라서 쓰면 된다.
MongoDB를 처음 사용해보는 것이여서 스프링 공식 문서와 baeldung 글을 읽고 시작했다.
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
의존성 추가
spring.data.mongodb.uri=mongodb://[ip 정보]:[port 정보]
spring.data.mongodb.database=[데이터베이스 이름]
/src/main/resource 밑에 application.properties 파일을 생성하고 위의 코드를 추가한다.
domain 패키지를 생성한다.
도메인을 담을 패키지이다. 도메인은 게시글, 댓글, 회원, 정산, 결제 등 소프트웨어에 대한 요구사항 혹은 문제영역을 말한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package com.example.springboot.domain.posts;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Getter
@NoArgsConstructor // 기본 생성자 자동 추가
@Document(collection="posts")
public class Posts {
@Id
private Long id;
private String title;
private String content;
private String author;
@Builder
public Posts(String title, String content, String author){
this.title = title;
this.content = content;
this.author = author;
}
}
|
cs |
이렇게 생성했더니
Cannot autogenerate id of type java.lang.Long for entity of type com.example.springboot.domain.posts.Posts!
오류가 났다. rdbms처럼 id가 자동증가가 되는 것이 아닌 모양..
https://www.baeldung.com/spring-boot-mongodb-auto-generated-field
이 사이트를 참고해서 자동생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package com.example.springboot.domain.posts;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Getter
@Setter //getters and setters omitted
@Document(collection = "database_sequences")//AUTO INCREMENT 연속성 정보 저장 컬렉션
public class DatabaseSequence {
@Id
private String id;
private long seq;
}
|
cs |
domain.posts 패키지 안에 DatabaseSequence.java 파일을 생성한다.
Posts.java로 돌아가서
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
package com.example.springboot.domain.posts;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;
@Getter
@NoArgsConstructor // 기본 생성자 자동 추가
@Document(collection="posts")
public class Posts {
@Transient // 영속성 필드 제외
public static final String SEQUENCE_NAME = "users_sequence";
// 자동 증가 시퀀스에 대해 참조하는 SEQUENCE_NAME 선언
@Id
private Long id;
private String title;
private String content;
private String author;
public void setId(Long id){
this.id = id;
}
@Builder
public Posts(String title, String content, String author){
this.title = title;
this.content = content;
this.author = author;
}
}
|
cs |
SEQUENCE_NAME을 static으로 선언한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package com.example.springboot.service.SequenceGenerator;
import com.example.springboot.domain.posts.DatabaseSequence;
import lombok.RequiredArgsConstructor;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import java.util.Objects;
import static org.springframework.data.mongodb.core.FindAndModifyOptions.options;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
@RequiredArgsConstructor
@Service
public class SequenceGeneratorService {
private final MongoOperations mongoOperations;
public long generateSequence(String seqName) {
DatabaseSequence counter = mongoOperations.findAndModify(query(where("_id").is(seqName)),
new Update().inc("seq",1), options().returnNew(true).upsert(true),
DatabaseSequence.class);
return !Objects.isNull(counter) ? counter.getSeq() : 1;
}
}
|
cs |
자동으로 증가시켜줄 수 있는 클래스인 SequenceGeneratorService.java를 생성한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package com.example.springboot.events;
import com.example.springboot.domain.posts.Posts;
import com.example.springboot.service.SequenceGenerator.SequenceGeneratorService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
import org.springframework.stereotype.Component;
@RequiredArgsConstructor
@Component
public class PostsModelListener extends AbstractMongoEventListener<Posts> {
private final SequenceGeneratorService sequenceGenerator;
@Override
public void onBeforeConvert(BeforeConvertEvent<Posts> event) {
// if (event.getSource().getId() < 1) {// null point error
event.getSource().setId(sequenceGenerator.generateSequence(Posts.SEQUENCE_NAME));
// }
}
}
|
cs |
mongoDB에 사용할 document를 만든다.
1
2
3
4
5
6
7
|
package com.example.springboot.domain.posts;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface PostsRepository extends MongoRepository<Posts,Long> {
}
|
cs |
MongoRepository를 extends한 인터페이스 PostsRepository를 작성한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
package com.example.springboot.web.domain.posts;
import static org.assertj.core.api.Assertions.assertThat;
import com.example.springboot.domain.posts.Posts;
import com.example.springboot.domain.posts.PostsRepository;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class PostsRepositoryTest {
@Autowired
PostsRepository postsRepository;
@After // 단위테스트가 끝날 때마다 수행되는 메소드
public void cleanup(){
postsRepository.deleteAll();
}
@Test
public void 게시글저장_불러오기(){
//given
String title = "테스트 게시글";
String content = "테스트 본문";
postsRepository.save(Posts.builder()
.title(title)
.content(content)
.author("작성자")
.build());
//when - 포스트 테이블 모두 조회
List<Posts> postsList = postsRepository.findAll();
//then
Posts posts = postsList.get(0);
assertThat(posts.getTitle()).isEqualTo(title);
assertThat(posts.getContent()).isEqualTo(content);
}
}
|
cs |
Test를 시도하면
deleteAll을 진행해서 post는 남지 않지만, database_sequences는 증가한 것을 확인할 수 있다.
'Web > SpringBoot' 카테고리의 다른 글
[SpringBoot/AWS EC2] MongoDB - 4 Delete, selectAll (0) | 2021.12.12 |
---|---|
[SpringBoot/AWS EC2] MongoDB - 3 Update (0) | 2021.12.12 |
[SpringBoot/AWS EC2] MongoDB - 2 등록 (0) | 2021.12.09 |
[SpringBoot/AWS EC2] Controller 생성 및 롬복 설치 (0) | 2021.12.06 |
[SpringBoot/AWS EC2] 인텔리제이 Project 생성 및 git 연동 (0) | 2021.12.05 |