controller 패키지에 ArticleController 생성
📄 ArticleController
@Controller
@Slf4j
public class ArticleController {
@GetMapping(value = "/articles/new")
public String newArticleForm(){
return "articles/new";
}
}
templates - articles diretory - new.mustache 생성
📄 new.mustache
{{>layouts/header}}
<form action="/articles/posts" method="post">
<div class="mb-3">
<label for="exampleFormControlInput1" class="form-label">Title</label>
<input name="title" type="text" class="form-control" id="exampleFormControlInput1">
</div>
<div class="mb-3">
<label for="exampleFormControlTextarea1" class="form-label">Contents</label>
<textarea name="content" class="form-control" id="exampleFormControlTextarea1" rows="5"></textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
<input type="reset" class="btn btn-primary" value="Reset">
</form>
{{>layouts/footer}}
📄 ArticleController
@PostMapping(value = "/posts")
public String createArticle(ArticleDto form){
log.info(form.toString());
return "articles/new";
}
@AllArgsConstructor
@Getter
@ToString
public class ArticleDto {
private Long id;
private String title;
private String content;
}
http://localhost:8080/articles/new
내용 입력 후 서버로 넘어오는 지 로그로 확인하기
build.gradle - dependencies에 아래 dependency 추가
implementation 'org.springframework.data:spring-data-jpa:2.7.5'
1) root directory에 entity package 생성 - Article class 생성
2) @Entity
, @Id
, @GeneratedValue
어노테이션을 붙여준다. - 거의 세트
어노테이션 설명글 참고
@Id가 없으면 아래와 같은 에러메시지가 나온다
📄 Article
@Entity
@NoArgsConstructor
@Getter
public class Article {
@Id
@GeneratedValue //자동으로 id를 생성한다.
private Long id;
@Column
private String title;
private String content;
public Article(String title, String content) {
this.title = title;
this.content = content;
}
}
3) ArticleDto에서 toEntity()
를 만들어준다.
public Article toEntity(){
return new Article(title, content);
}
4) controller에서 Article 객체를 반환하도록 리팩토링한다.
@PostMapping(value = "/posts")
public String createArticle(ArticleDto form){
log.info(form.toString());
Article article = form.toEntity();
return "articles/new";
}
📄 application.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/likelion-db
username: root
password: 12345
나중에 환경변수로 진짜 url을 넘겨준다.
SPRING_DATASOURCE_URL=jdbc:mysql://[ec2주소]:3306
리포지토리를 생성하기 위해서는 접근하려는 테이블과 매핑되는 엔티티에 대한 인터페이스를 생성하고, JpaRepository를 상속받으면 된다.
JpaRepository를 상속받을 때는 대상 엔티티(Article)와 해당 엔티티의 기본값 타입 (Long)을 지정해야 한다.
생성된 리포지토리는 JpaRepository를 상속받으면서 별도의 메서드 구현 없이도 많은 기능을 제공한다. 일반적으로 CRUD에서 따로 생성해서 사용하는 메서드는 Read에 해당하는 SELECT 쿼리밖에 없다.
1) 📄 ArticleRepository interface
@Repository
public interface ArticleRepository extends JpaRepository<Article, Long>{
}
2) controller에 생성자를 이용하여 DI & DTO를 entity로 변환
public class ArticleController {
private final ArticleRepository articleRepository;
public ArticleController(ArticleRepository articleRepository) {
this.articleRepository = articleRepository;
}
...
@PostMapping(value = "/posts")
public String createArticle(ArticleDto form){
log.info(form.toString());
Article article = form.toEntity();
articleRepository.save(article); //JPA가 알아서 생성해준다.
return "articles/new";
}
}
📄 application.yml
jpa:
show-sql: true # jpa가 자동으로 만들어주는 query문을 콘솔에 출력
database-platform: org.hibernate.dialect.MySQL8Dialect # 사용할 DB의 Dialect 설정
database : mysql # 사용할 DB 종류
hibernate.ddl-auto : update #가장 중요한 옵션!!!!초보일 때 create 쓰지 말 것!!!!!
💡 ddl-auto 옵션
create, update 쓸 때 매우 주의, 비교적 덜 위험한 validate 사용 권장
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table article (id bigint not null, content varchar(255), title varchar(255), primary key (id)) engine=InnoDB" via JDBC Statement
⭕️ 해결
mysql이 내려가서 schema도 다시 생성해주었다. (환경변수도 url 뒤에 /likelion 추가)
✅ 콘솔에 쿼리 출력 확인
✅ 워크벤치로 테이블, 데이터 생성 확인