220419~220420 TIL


学習資料


Honoxの羽毛コード

学習のきっかけ

  • トッピングの場合、テーブルを簡単に定義しています.
  • 一つの料理が一つのテーブルと1:Nの関係になる.
  • 1:N関係の場合、1つの料理と対応する料理idのすべての画像を1つのオブジェクトにすることができますか?複数回クエリーを送信して組み合わせる方法ではなく、joinでは解決できませんか?
  • この考えはほぼ2日間にわたって捨てられた.そしてこれらの悩みに対して、やはり優秀な先輩開発者たちがすべての技術を用意してくれているので、私たちはこれらの技術の使い方と原理を学べばいいのです.
  • 事前に勉強資料を見ていたら?Springdata Jdbcの基本的な学習に欠けている場合は?事前にJPAを勉強していたら?残念ですね.
  • SpringDataJdbc oneToMany

  • 例題コードは文章と評論であり,投稿と評論は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対象
  • 外部キー情報はありません.
  • 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を利用しますか?

  • 多くのテーブルに相当する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;

    テストすると。

  • 対象として保存し、来たときに注釈を見つけてリストタイプの注釈として置く.
  • 推定は内部に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

  • 内部論理と原理は推測にすぎない.
  • またOneToOneManyToManyEmbedded関連の使い方は未整理.
  • 公式文書を閲覧し、キーワードを知り、JPAのようなところが多いので、なるべく早くjpaに入るべきです.