한 줄 정의 : JPA는 인터페이스 형태로 method를 호출하는 형태로 데이터베이스를 핸들링한다.
[ JPA란? ]
JPA(ORM) : 여지껏 Mybatis(SQL Mapper) 환경으로 DB처리를 했는데, JPA로도 Mybatis 환경을 처리할 수 있다.
JPA는 SQL문을 기본적으로 사용하지 않는다. (사용할 수는 있음)
JPA를 사용하면 데이터베이스의 데이터를 자바 객체로 매핑하고, 객체를 통해 데이터베이의 CRUD(Create, Read, Update, Delete) 작업을 수행할 수 있다.
ORM(Object Relationship Mapper)
@Repository : 저장소 (Spring Boot에서의 Dao) Data를 다루는 객체 < JPA는 @Repository Component이다.>
SQL문이 없이, 직속적으로 findAll(), findById(id), findByName(name)와 같은 Method를 사용해서, SQL문을 사용하지 않고도, JPA가 SQL문을 대신해서 작성해주고 전달해준다.
사용방법 : interface DeptRepository extends JpaRepository<Dept, Integer>
(
List<Dept> findAll();
)
SQL에서의 insert -> save(Dept);
[ JPA 실전사용 ]
start.spring.io에 들어가서 세팅 해준다.
spring.application.name=demo_jpa
# Spring DataSource (Oracle)
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:xe
spring.datasource.username=test
spring.datasource.password=test
# Spring JPA(Oracle)
spring.jpa.database=oracle
spring.jpa.database-platform=org.hibernate.dialect.OracleDialect
# 공통
spring.jpa.hibernate.ddl-auto=none
# ddl에 true를 주게 되면 drop-table -> create table
spring.jpa.generate-ddl=false
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate=info
Entity가 기존에 Vo역할이라고 생각하면 될 거 같다.
[ JPA Column 속성 ]
Repository 생성하기(Dao 개념)
findAll()은 따로 DeptRepository에 적용하지 않아도 자동으로 생성이 되어서 Controller에서 호출해서 사용할 수 있다.
[ @RestController = @Controller + @ResponseBody ]
JPA의 Controller는 RestAPI로 움직인다.
package com.githrd.demo_jpa.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.githrd.demo_jpa.entity.Dept;
// @RestController = @Controller + @ResponseBody
import com.githrd.demo_jpa.repository.DeptRepository;
@RestController
public class DeptController {
// Dao 가져오기
@Autowired
DeptRepository deptRepository;
@GetMapping("/depts")
public List<Dept> list() {
List<Dept> list = deptRepository.findAll();
return list;
}
}
이렇게 하면, DataBase를 JPA가 알아서 가져온다.
Rest API로 JSON을 정상적으로 가져온다.
[ selectOne에서 Optional 활용해보기 ]
optional은 selectOne에서 인자값으로 넣는 값이 없을 수도 있다는 가정하에 쓰는것임
RestController 설정하기
결과값
[ UI 만들어서 출력해보기 ]
SPA(Single Page Application)으로 만들어보겠다.
파일 경로
index.html을 SPA로 활용해보자.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<style>
@font-face {
font-family: 'CookieRun-Regular';
src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/noonfonts_2001@1.1/CookieRun-Regular.woff') format('woff');
font-weight: normal;
font-style: normal;
}
* {
font-family: 'CookieRun-Regular';
font-weight: bold;
}
#box {
width: 900px;
margin: auto;
margin-top: 50px;
}
h1 {
text-align: center;
font-size: 28px;
color: black;
}
a {
font-size: 16px;
font-weight: bold;
text-decoration: none !important;
margin-right: 50px;
margin-left: 50px;
}
a:hover {
color: rgb(31, 146, 212);
}
nav {
text-align: center;
}
hr {
color: skyblue !important;
height: 1px !important;
}
th, td {
text-align: center;
font-weight: bold;
vertical-align: middle !important;
}
</style>
<script>
// 화면 시작시, dept_list 호출
$(document).ready(function(){
dept_list();
});
function dept_list() {
// Ajax : Rest API
$.ajax({
url : "/depts",
dataType : "json",
success : function(res_data){
// json은 배열로 들어오기 때문에, dept_array 변수로 받아준다.
let dept_array = res_data;
let html =
`<table class="table">
<tr class="success">
<th>부서번호</th>
<th>부서명</th>
<th>위치</th>
<th>편집</th>
</tr>
`;
// for(Dept dept : dept_array)
// Data 넣는 코드(javaScript에서의 foreach문)
for(let dept of dept_array) {
html +=
`
<tr>
<td>${ dept.deptno }</td>
<td>${ dept.dname }</td>
<td>${ dept.loc }</td>
<td>
<input class="btn btn-info" type="button" value="수정">
<input class="btn btn-danger" type="button" value="삭제">
</td>
</tr>
`;
}
// 마무리 코드
html += `</table>`;
$("#root").html(html);
},
error : function(err){
alert(err.responseText);
}
});
}// end:dept_list()
// 등록폼 띄우기
function dept_form() {
let html =
`
<div class="panel panel-primary">
<div class="panel-heading">부서등록</div>
<div class="panel-body">
<div style="margin-bottom: 20px;">
부서명 :
<input class="form-control" id="dname">
</div>
<div>
부서위치 :
<input class="form-control" id="loc">
</div>
<div>
<input class="btn btn-primary" type="button" value="등록하기" onclick="dept_insert();">
</div>
</div>
</div>
`;
$("#root").html(html);
}// end:dept_form()
function dept_insert() {
let dname = $("#dname").val().trim();
let loc = $("#loc").val().trim();
if(dname=='') {
alert("부서명을 입력하세요.");
$("#dname").val("");
$("#dname").focus();
return;
}
if(loc=='') {
alert("부서위치를 입력하세요.");
$("#loc").val("");
$("#loc").focus();
return;
}
// Ajax 통해서 insert : POST /dept {"dname":"","loc":""}
let dept = `{"dname":"${dname}","loc":"${loc}"}`;
$.ajax({
type : "POST", // Rest API insert
contentType : "application/json",
url : "/dept",
data : dept,
dataType : "json",
success : function(res_data){
// res_data = {"result":true} or {"result":false}
if(res_data.result==false) {
alert("등록실패!!!");
return;
}
alert("부서가 등록되었습니다.");
dept_list();
},
error : function(err){
alert(err.responseText);
}
});
}// end:dept_insert()
</script>
</head>
<body>
<div id="box">
<h1>부서</h1>
<hr>
<!-- nav:Menu 상징적 태그 (기능은 없음) -->
<nav>
<a href="#" onclick="dept_list();">목록보기</a>
<a href="#" onclick="dept_form();">부서등록</a>
</nav>
<hr>
<div id="root"></div>
</div>
</body>
</html>
[ Save - Insert, Update ]
[ JPQL문과 SQL문의 JPA에서의 사용 ]
'SpringBoot↗' 카테고리의 다른 글
Spring Boot)Transaction (0) | 2024.08.12 |
---|---|
Spring Boot)JPA로 Sawon 데이터 활용하기 (0) | 2024.08.12 |
SpringBoot 환경설정 및 초기 가이드 (0) | 2024.08.07 |
Spring)RMI (0) | 2024.08.07 |
Spring)Transaction - AOP (0) | 2024.08.06 |