220419~220420 TIL
18144 단어 SpringDataJDBCTILSpringDataJDBC
학습자료
호눅스의 깃헙코드
학습계기
- 반찬 프로젝트를 진행하면서 간단하게 테이블을 정의했다.
- 하나의 dish와 image 테이블은 1:N 관계를 맺는다.
- 1:N 관계를 가졌을때, 하나의 dish와 해당하는 dish의 id를 가지는 모든 image를 하나의 객체로 만들 수는 없을까? 여러번의 쿼리를 보내서 조합하는 방법이 아닌 join으로는 해결할 수 없을까?
- 이 생각이 거의 이틀 가까이 삽질을 하게 했다. 그리고 이러한 고민에 대해서는 역시나 멋진 선배 개발자들은 기술을 다 마련해놓으셨고, 우리는 그 기술의 사용법과 원리를 공부하면 되는 것이었다.
- 학습자료를 미리 봤다면?, Spring data Jdbc에 대한 기본 공부를 조금했더라면? Jpa를 미리 공부했다면? 아쉽다.
SpringDataJdbc oneToMany
- 예제 코드는 article과 comment, 게시글과 댓글은 1:N 관계이다.
create table if not exists article
(
id bigint primary key auto_increment,
author varchar(50)
);
create table if not exists comment
(
id bigint primary key auto_increment,
contents varchar(255),
// foreign key를 해당하는 table명으로 하는 것이 default이다.
article bigint references article(id)
);
- Article 객체
public class Article {
@Id
private Long id;
private String author;
// article의 id를 가지는 comment들을 가져와 저장할 수 있도록 하는 set
private Set<Comment> comments;
public Article(String author, Set<Comment> comments) {
this.author = author;
this.comments = comments;
}
public Long getId() {
return id;
}
public String getAuthor() {
return author;
}
public Set<Comment> getComments() {
return comments;
}
@Override
public String toString() {
return "Article{" +
"id=" + id +
", author='" + author + '\'' +
", comments=" + comments +
'}';
}
//CrudRepository를 활용
@Repository
public interface ArticleRepository extends CrudRepository<Article, Long> {
}
- Comment 객체
- foreign key 정보는 가지고 있지않다.
public class Comment {
@Id
private Long id;
private String contents;
public Comment(String contents) {
this.contents = contents;
}
public String getContents() {
return contents;
}
@Override
public String toString() {
return "Comment{" +
"id=" + id +
", contents='" + contents + '\'' +
'}';
}
set이 아닌 List나 Map을 활용하려면?
- many에 해당하는 table에 _key라는 컬럼이 필요하다. 인덱스 혹은 key에 해당하는 정보를 담기 위한 것 같다.
// article의 의미를 더 명확하게 전달하기 위해서 article_id로 컬럼 네이밍 변경
// list활용을 위한 column article_key
create table if not exists comment
(
id bigint primary key auto_increment,
contents varchar(255),
article_id bigint references article(id),
article_key int
);
// list를 활용하는 버전
public class Article {
@Id
private Long id;
private String author;
// column 네이밍 설정을 위한 어노테이션, 왜인지는 모르겠으나 소문자로했을때 DbActionExecutionException 발생했다.
@MappedCollection(idColumn = "ARTICLE_ID")
private List<Comment> comments;
테스트를 해보면
- 객체로 저장을 하고, 찾아올때도 comment도 다 찾아서 list 타입의 comment로 잘 넣어준다.
- 아마 내부적으로 join을 하는 쿼리와 중복되는 raw들에 대해서 맵핑하는 것으로 추측한다.
@DataJdbcTest
class ArticleRepositoryTest {
@Autowired
ArticleRepository articleRepository;
@Test
void save_find_Test() {
List<Comment> comments = List.of(new Comment("123"), new Comment("321"));
Article ron2Article = new Article("ron2", comments);
Article saved = articleRepository.save(ron2Article);
Article article = articleRepository.findById(1L).orElseThrow();
assertThat(article.getComments()).hasSize(2);
assertThat(article.getComments()).contains(new Comment("123"));
assertThat(article.getComments()).contains(new Comment("321"));
// 테스트를 위해서 Coment 객체의 equals 메서드를 contents만 같은지 확인하도록 overriding 했습니다.
}
TODO
- 내부로직과 원리에 대해서 아직은 추측만을 하고 있다.
- 또한
OneToOne
,ManyToMany
,Embedded
와 관련한 사용법에 대해서 아직 정리하지 못했다. - 공식문서를 훑어보면서 키워드에 대해서도 알아보고, Jpa와 흡사한 부분이 많으니 얼른 jpa에도 입문해야겠다.
Author And Source
이 문제에 관하여(220419~220420 TIL), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@cmsskkk/220420220421-TIL저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)