Spring Boot でアプリを作成してみた【Blog Application】

## 1. start.spring.io でプロジェクトを作成する

(1) ブラウザを開き、(https://start.spring.io/) を入力し、開く
(2) 下記を入力し、Dependenciesで下記を選択し、『GENERATE』ボタンを押す

- Project: Maven
- Language: Java
- SpringBoot: 3.3.2

- Group: com.example
- Artifact: blog-app
- Name : blog-app
- Description: Demo project for spring Boot
- Package name: com.example.blog-app

Dependencies
- Spring Web
- Spring Data JPA
- MySQL Driver
- Lombok

## 2. java/com.example/blog_appにパッケージとファイルを作成する
(1)java/com.example/blog_appにbeanパッケージとPost.javaを作成する

```java/com.example/blog_app/bean/Post.java
package com.example.blog_app.bean;

import jakarta.persistence.*;
import lombok.*;

import java.util.*;

@Entity
@Table(name = "posts")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;

    @Column
    String title;

    @Column
    String description;

    @OneToMany(mappedBy = "post")
    List<Comment> comments = new ArrayList<>();
}
```
(2)java/com.example/blog_appにcontrollerパッケージとPostController.javaを作成する
```java/com.example/blog_app/controller/PostController.java
package com.example.blog_app.controller;

import com.example.blog_app.bean.Post;
import com.example.blog_app.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@RestController
public class PostController {

    @Autowired
    private PostService postService;

    @PostMapping("/createPost")
    public ResponseEntity<String> createPost(@RequestBody Post post) {
        Post response = postService.createPost(post);

        return new ResponseEntity<>("Post created successfully. Id -> " + response.getId(), HttpStatus.CREATED);
    }

    @GetMapping("/getPost/{id}")
    public ResponseEntity<Post> getPostById(@PathVariable Long id) {
        Post response = postService.getPostById(id);

        return ResponseEntity.ok(response);
    }

    @GetMapping("/getPosts")
    public List<Post> getAllPost() {
        return postService.getAllPost();
    }

    @PutMapping("/updatePost/{id}")
    public ResponseEntity<String> updatePost(@RequestBody Post post, @PathVariable Long id) {
        postService.updatePostById(post, id);

        return new ResponseEntity<>("Post updated successfully.", HttpStatus.OK);
    }

    @DeleteMapping("/deletePost/{id}")
    public ResponseEntity<String> deletePost(@PathVariable Long id) {
        postService.deletePostById(id);

        return new ResponseEntity<>("Post deleted successfully.", HttpStatus.OK);
    }
}
```

(3)java/com.example/blog_app/controllerにCommentController.javaを作成する

```java/com.example/blog_app/controller/CommentController.java
package com.example.blog_app.controller;

import com.example.blog_app.bean.Comment;
import com.example.blog_app.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class CommentController {

    @Autowired
    private CommentService commentService;

    @PostMapping("/posts/{id}/addComment")
    public ResponseEntity<String> addComment(@RequestBody Comment comment, @PathVariable Long id) {
        Comment response = commentService.addComment(comment, id);

        return new ResponseEntity<>("Comment created successfully. Id -> " + response.getId(), HttpStatus.CREATED);
    }

    @GetMapping("/comment/{id}")
    public ResponseEntity<Comment> getCommentByCommentId(@PathVariable Long id) {
        Comment comment = commentService.getCommentByCommentId(id);

        return ResponseEntity.ok(comment);
    }

    @GetMapping("/post/{id}/getComments")
    public List<Comment> getCommentByPostId(@PathVariable Long id) {
        return commentService.getCommentByPostId(id);
    }

    @PutMapping("/post/{postId}/comment/{commentId}")
    public ResponseEntity<String> updateComment(@PathVariable Long postId, @PathVariable Long commentId,
            @RequestBody Comment comment) {
        commentService.updateCommentByCommentId(commentId, postId, comment);

        return new ResponseEntity<>("Comment updated successfully.", HttpStatus.OK);
    }

    @DeleteMapping("/deleteComment/{id}")
    public ResponseEntity<String> deleteComment(@PathVariable Long id) {
        commentService.deleteCommentByCommentId(id);

        return new ResponseEntity<>("Comment deleted successfully.", HttpStatus.OK);
    }

}
```

(4)src/main/resouces/application.propertiesを編集する

```src/main/resouces/application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/blog_app
spring.datasource.username=root
spring.datasource.password=root

spring.jpa.hibernate.ddl-auto=update
```


(5)java/com.example/blog_appにdaoパッケージとPostDao.javaを作成する

```java/com.example/blog_appにdao/PostDao.java
package com.example.blog_app.dao;

import com.example.blog_app.bean.Post;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface PostDao extends JpaRepository<Post, Long> {

}
```

(6)java/com.example/blog_appにserviceパッケージとPostService.javaを作成する

```java/com.example/blog_app/service/PostService.java
package com.example.blog_app.service;

import com.example.blog_app.bean.Post;
import com.example.blog_app.dao.PostDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class PostService {

    @Autowired
    private PostDao postDao;

    public Post createPost(Post post) {
        return postDao.save(post);
    }

    public Post getPostById(Long id) {
        return postDao.findById(id).orElseThrow(() -> new RuntimeException(id + " -> This id doesn't exists"));
    }

    public List<Post> getAllPost() {
        return postDao.findAll();
    }

    public void updatePostById(Post post, Long id) {
        if (postDao.findById(id).isPresent()) {
            Post newPost = new Post();
            newPost.setId(id);
            newPost.setTitle(post.getTitle());
            newPost.setDescription(post.getDescription());

            postDao.save(newPost);
        } else {
            throw new RuntimeException(id + " -> This id doesn't exists");
        }
    }

    public void deletePostById(Long id) {
        if (postDao.findById(id).isPresent()) {
            postDao.deleteById(id);
        } else {
            throw new RuntimeException(id + " -> This id doesn't exists");
        }
    }
}
```

(7)java/com.example/blog_app/beanにComment.javaを作成する

```java/com.example/blog_app/bean/Comment.java
package com.example.blog_app.bean;

import jakarta.persistence.*;
import lombok.*;

@Entity
@Table(name = "comments")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class Comment {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column
    private String name;
    @Column
    private String email;
    @Column
    private String comment_desc;

    @ManyToOne
    @JoinColumn(name = "post_id")
    private Post post;
}
```

(8)java/com.example/blog_app/daoにCommentDao.javaを作成する

```java/com.example/blog_app/dao/CommentDao.java
package com.example.blog_app.dao;

import com.example.blog_app.bean.Comment;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.*;

@Repository
public interface CommentDao extends JpaRepository<Comment, Long> {
    public List<Comment> findByPostId(Long postId);
}

```

(9)java/com.example/blog_app/serviceにCommentService.javaを作成する

```java/com.example/blog_app/service/CommentService.java
package com.example.blog_app.service;

import com.example.blog_app.bean.Comment;
import com.example.blog_app.bean.Post;
import com.example.blog_app.dao.CommentDao;
import com.example.blog_app.dao.PostDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class CommentService {

    @Autowired
    private PostDao postDao;

    @Autowired
    private CommentDao commentDao;

    public Comment addComment(Comment comment, Long postId) {
        Post post = postDao.findById(postId)
                .orElseThrow(() -> new RuntimeException(postId + " -> This post id doesn't exists"));
        comment.setPost(post);

        return commentDao.save(comment);
    }

    public Comment getCommentByCommentId(Long id) {
        return commentDao.findById(id)
                .orElseThrow(() -> new RuntimeException(id + " -> This id doesn't exists"));
    }

    public List<Comment> getCommentByPostId(Long postId) {
        return commentDao.findByPostId(postId);
    }

    public void updateCommentByCommentId(Long commentId, Long postId, Comment comment) {
        Post post = postDao.findById(postId)
                .orElseThrow(() -> new RuntimeException(postId + " -> This post id doesn't exists"));

        comment.setId(commentId);
        comment.setPost(post);

        commentDao.save(comment);
    }

    public void deleteCommentByCommentId(Long id) {
        if (commentDao.findById(id).isPresent()) {
            commentDao.deleteById(id);
        } else {
            throw new RuntimeException(id + " -> This id doesn't exists");
        }
    }
}
```


## 参考サイト
[Part - 1 | Simple REST Project | Blog Application | Spring Boot | JPA | MySQL | Beginners | Tutorial](https://www.youtube.com/watch?v=Mc_QP37rP3g)
[Part - 2 | Simple REST Project | Blog Application | Spring Boot | JPA | MySQL | Beginners | Tutorial](https://www.youtube.com/watch?v=nEd-qm7RW5I)