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/

 

+ Recent posts