1. JPA(Java Persistence API)
- 자바의 ORM 기술 표준 명세로 Java에서 제공하는 API
- 자바 어플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스
- ORM이기 때문에 자바 클래스와 DB테이블을 매핑(SQL을 매핑하지않음)
- ORM을 사용하기 위한 인터페이스를 모아둔 것이며, JPA를 사용하기 위해서는 JPA를 구현한 Hibernate, EclipseLink,
DataNucleus같은 ORM 프레임워크를 사용해야 함
* ORM : 객체와 DB를 연결해주는 기술
1) spring.jpa.hibernate.ddl-auto 옵션
- create : 새로운 테이블 생성
- createdrop : 기존 테이블을 지우고 새로 생성
- none : 수동으로 직접 테이블을 생성해야함
- update : 현재 테이블 있으면 만들지 말고 데이터 누적. 테이블이 없으면 새로 생성(많이 사용).
시작 시 도메인과 스키마 비교하여 필요한 컬럼 추가 등의 작업 실행. 데이터는 삭제하지 않음.
- validate : 기존과 새로운 것의 달라진 내용만 표시해줌. 스키마가 적합한지 검사함. 문제가 있으면 예외 발생.
2) spring.jpa.properties.hibernate.format_sql 옵션
- 콘솔에 sql 코드 보여질 때 문단 정리
3) spring.jpa.show-sql 옵션
- 실행했을 때 콘솔에 sql 코드 보여지기
4) spring.jpa.hibernate.naming.physical-strategy 옵션
- 엔티티클래스의 카멜 케이스 필드명을 DB의 스네이크 케이스 컬럼명으로 자동 매핑
(테스트 예제)
File ▶ New ▶ Spring Starter Project ▶ Name : test4 / Group : com.example.test4 / Artifact : test4 / Package : com.example.test4 ▶ Lombok, DevTool, Sprig Web, oracle, JDBC, Spring Data JPA 선택
▶ application. properties 파일
#view resolver spring.mvc.view.prefix=/WEB-INF/views/ spring.mvc.view.suffix=.jsp #jdbc spring.datasource.driver-class-name=oracle.jdbc.OracleDriver spring.datasource.url=jdbc:oracle:thin:@localhost:1521:xe spring.datasource.username=fin02 spring.datasource.password=fin02 #spring data jpa spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.format_sql=true spring.jpa.show-sql=true spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl |
▶ pom.xml 파일
<!--JSP, JSTL--> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>jakarta.servlet.jsp.jstl</artifactId> </dependency> <dependency> <groupId>jakarta.servlet.jsp.jstl</groupId> <artifactId>jakarta.servlet.jsp.jstl-api</artifactId> </dependency> <!--톰캣--> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency> |
▶ src/main/java 폴더에 패키지 생성
- com.example.test4.controller
- com.example.test4.dto
- com.example.test4.entity
- com.example.test4.repository
▶ index.jsp
<html> <head> <meta charset="UTF-8"> <title>JPA 실습</title> </head> <body> <a href="/articles"> 글목록으로 가기 </a> </body> </html> |
▶ com.example.test4.entity 패키지에 Article.java 파일 생성
▶ Article.java
@Entity // 클래스명이 테이블명이 됨. 만약 테이블명을 다르게 하고 싶으면 @Table(name = "board")라고 @Entity 밑에 써야함. // import jakarta.persistence.Table; @NoArgsConstructor // 디폴트 생성자 @AllArgsConstructor // 전체 생성자 @Getter // Getter 메서드 @SequenceGenerator( // sequence 정의 name = "article_seq_generator", sequenceName = "article_seq", initialValue = 1, allocationSize = 1) public class Article { @Id // primary key @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "article_seq_generator") private Long id; @Column private String title; @Column private String content; } |
▶com.example.test4.repository 패키지에 ArticleRepository 인터페이스 생성
▶ ArticleRepository.java
public interface ArticleRepository extends CrudRepository<Article, Long>{ // CrudRepository를 이용해서 Aritcle DB에 있는 데이터 가져오기 @Override ArrayList<Article> findAll(); // CrudRepository가 가지고 있는 findAll 메서드를 오버라이드 } |
▶ ArticleController
@Controller public class ArticleController { @Autowired ArticleRepository articleRepository; @GetMapping("/") public String index() { return "index"; } @GetMapping("/articles") public String list(Model model) { // 1. DB에 있는 모든 데이터 가져오기 List<Article> articleEntityList = articleRepository.findAll(); // 2. 가져온 데이터를 모델에 넣기 model.addAttribute("articleList", articleEntityList); // 3. view 페이지로 이동하기 return "list"; } } |
▶ list.jsp
<html> <head> <title>list</title> </head> <body> <div align="center"> <hr color="green" width="300"> <h2>게 시 판 리 스 트</h2> <a href="/articles/new">글쓰기</a> <hr color="green" width="300"> <table border="1" width="500"> <tr bgcolor="yellow"> <th>번호</th> <th>제목</th> <th>내용</th> </tr> <c:if test="${empty articleList}"> <tr> <td colspan="3">등록된 게시글이 없습니다.</td> </tr> </c:if> <c:forEach var="dto" items="${articleList}"> <tr> <td>${dto.id}</td> <td>${dto.title}</td> <td>${dto.content}</td> </tr> </c:forEach> </table> </div> </body> </html> |
▶ ArticleController
@GetMapping("/articles/new") public String articleForm() { return "inputForm"; } |
▶ inputForm.jsp
<html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form name="f" action="/articles/create" method="post"> 제목 : <input type="text" name="title"><br> 내용 : <input type="text" name="content"><br> <input type="submit" value="전송"> </form> </body> </html> |
▶ ArticleForm (DTO) 에 생성자 추가
public Article toEntity() { return new Article(id, title, content); } |
▶ ArticleController
@GetMapping("/articles/new") public String articleForm() { return "inputForm"; } @PostMapping("/articles/create") public String createArticle(@ModelAttribute ArticleForm articleForm) { // @ModelAttribute 생략가능 //1. DTO를 엔티티로 변환 Article article = articleForm.toEntity(); //2. Repository로 엔티티를 DB에 저장 Article saved = articleRepository.save(article); System.out.println(saved.toString()); return "redirect:/articles"; } |
▶http://localhost:8080/ 실행
▶list.jsp
<html> <head> <title>list</title> </head> <body> <div align="center"> <hr color="green" width="300"> <h2>게 시 판 리 스 트</h2> <a href="/articles/new">글쓰기</a> <hr color="green" width="300"> <table border="1" width="500"> <tr bgcolor="yellow"> <th>번호</th> <th>제목</th> <th>내용</th> </tr> <c:if test="${empty articleList}"> <tr> <td colspan="3">등록된 게시글이 없습니다.</td> </tr> </c:if> <c:forEach var="dto" items="${articleList}"> <tr> <td><a href="/articles/${dto.id}">${dto.id}</a></td> <td>${dto.title}</td> <td>${dto.content}</td> </tr> </c:forEach> </table> </div> </body> </html> |
▶ ArticleController
@GetMapping("/articles/{id}") // {id}에 파라미터값 들어옴 public String getArticle(@PathVariable Long id, Model model) { // {id} 값이 Pathvariable를 통해 id로 들어옴 System.out.println("id = " + id); //Optional article= articleRepository.findById(id); // 원래 자료형은 Optional임 Article article = articleRepository.findById(id).orElse(null); // orElse를 적으면 Article 객체로 받을 수 있음 model.addAttribute("getArticle", article); return "show"; } |
▶ show.jsp
<html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form name="f" action="/articles/update" method="post"> 번호 : <input type="text" name="id" value="${getArticle.id}" readOnly> <br> 제목 : <input type="text" name="title" value="${getArticle.title}"><br> 내용 : <input type="text" name="content" value="${getArticle.content}"><br> <input type="button" value="삭제" onclick="location.href='/article/${getArticle.id}/delete'"> <input type="submit" value="수정"> </form> </body> </html> |
▶ ArticleController
@PostMapping("/articles/update") public String update(ArticleForm articleform) { //1.DTO를 엔티티로 변환하기 Article article = articleform.toEntity(); //2.엔티티를 DB에 저장하기 Article target = articleRepository.findById(article.getId()).orElse(null); // DB에서 기존 데이터 가져오기 if (target != null) { // 기존 데이터가 있는지 확인하고 있으면 udpate articleRepository.save(article); } //3.수정 후 결과 페이지로 이동하기 return "redirect:/articles/"+article.getId(); // return "redirect:/articles/"; // 목록으로 } @GetMapping("/article/{id}/delete") public String delete(@PathVariable Long id) { //1. 삭제할 대상을 가져오기 Article article = articleRepository.findById(id).orElse(null); //2. 대상 엔티티를 삭제하기 if (article != null) { articleRepository.delete(article); } //3. 삭제 후 목록 페이지로 이동하기 return "redirect:/articles"; } |
2. 특수 쿼리문 (직접 쿼리문 작성)
▶ ArticleRepository.java
@Transactional // 직접 쿼리 작성할때 반드시 필요 @Modifying(clearAutomatically = true) @Query(value="update article set content='kkk' where id = :id", nativeQuery=true) // :id는 값을 전달 받게됨 int updateTest(@Param("id")Long id); |
▶ ArticleController
@GetMapping("/") public String index() { int res = articleRepository.updateTest(1L); return "index"; } |
▶http://localhost:8080/
'KDT - 풀스택 개발 과정 > SPRING BOOT' 카테고리의 다른 글
[DAY_56] Spring Boot - 게시판 예제, Lombok (0) | 2024.07.31 |
---|---|
[DAY_55] Spring Boot - 설치 및 세팅, 회원관리 (0) | 2024.07.29 |