1) SpringBoot
1-1) Server, JPA, DB 예제
1-1-1) form 입력값 저장
1-1-2) 검색 결과 출력
1-2) 추가 정리사항
1) SpringBoot
1-1) Server, JPA, DB 예제
[src/main/resources] - [templates] 안에 home.html 파일 생성 후 아래와 같이 작성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>web3</title>
</head>
<body>
<h1>[ web3 ]</h1>
<p>
<a href="test">저장 테스트</a>
</p>
<p>
<a href="save">사용자 입력값을 저장</a>
</p>
<p>
<a href="select">사용자 정보 조회</a>
</p>
</body>
</html>
1-1-1) form 입력값 저장
(1) [src/main/java] - [net.datasa.web3] 안에 PersonController.java 파일 생성 후 아래와 같이 작성
package net.datasa.web3;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RequiredArgsConstructor
@Controller
public class PersonController {
private final PersonService personService;
@GetMapping("test")
public String test() {
personService.test();
return "redirect:/";
}
/**
* 입력 폼으로 이동
* @return Form이 있는 HTML 파일 경로
* */
@GetMapping("save")
public String save() {
return "inputForm";
}
/**
* form의 입력값을 받아서 저장
* */
@PostMapping("save")
public String save(@ModelAttribute PersonDTO dto) {
log.debug("전달된 값 : {}", dto);
personService.save(dto);
return "redirect:/";
}
}
(2) [src/main/resources] - [templates] 안에 inputForm.html 파일 생성 후 아래와 같이 작성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>저장</title>
</head>
<body>
<h1>[ 저장 ]</h1>
<form action="save" method="post">
아이디 <input type="text" name="id"><br>
이름 <input type="text" name="name"><br>
나이 <input type="number" name="age"><br>
<input type="submit" value="저장"><br>
</form>
</body>
</html>
(3) [src/main/java] - [net.datasa.web3] 안에 PersonDTO.java 파일 생성 후 아래와 같이 작성
package net.datasa.web3;
import lombok.Data;
@Data
public class PersonDTO {
String id;
String name;
int age;
}
(4) [src/main/java] - [net.datasa.web3] 안에 PersonService.java 파일 생성 후 아래와 같이 작성
package net.datasa.web3;
//import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Service
@Transactional
public class PersonService {
// 이렇게 작성해도 되지만 아래의 방식이 더 권장된다!
// @Autowired
// PersonRepository PersonRepository;
private final PersonRepository personRepository;
public void test() {
PersonEntity entity = new PersonEntity();
entity.setId("abcde2");
entity.setName("김길동");
entity.setAge(22);
personRepository.save(entity);
}
public void save(PersonDTO dto) {
PersonEntity entity = new PersonEntity();
entity.setId(dto.getId());
entity.setName(dto.getName());
entity.setAge(dto.getAge());
personRepository.save(entity);
}
}
(5) [src/main/java] - [net.datasa.web3] 안에 PersonRepository.java 파일 생성 후 아래와 같이 작성
package net.datasa.web3;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface PersonRepository extends JpaRepository<PersonEntity, String> {
}
(6) [src/main/java] - [net.datasa.web3] 안에 PersonEntity.java 파일 생성 후 아래와 같이 작성
package net.datasa.web3;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;
@Data
@Entity
@Table(name="person")
public class PersonEntity {
@Id
@Column(name = "id", nullable = false, length = 30)
private String id;
@Column(name = "name", length = 50)
private String name;
@Column(name = "age")
private Integer age;
}
(7) 결과 화면
첫 접속 화면
"사용자 입력값을 저장" 문구 클릭 시 화면
Input Box에 입력값을 각각 입력 후 "저장" 버튼 클릭 후 DBeaver 결과 조회 화면
1-1-2) 검색 결과 출력
(1) [src/main/java] - [net.datasa.web3] 안에 PersonController.java 파일 생성 후 아래와 같이 작성
package net.datasa.web3;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RequiredArgsConstructor
@Controller
public class PersonController {
private final PersonService personService;
@GetMapping("test")
public String test() {
personService.test();
return "redirect:/";
}
/**
* 입력 폼으로 이동
* @return Form이 있는 HTML 파일 경로
* */
@GetMapping("save")
public String save() {
return "inputForm";
}
/**
* form의 입력값을 받아서 저장
* */
@PostMapping("save")
public String save(@ModelAttribute PersonDTO dto) {
log.debug("전달된 값 : {}", dto);
personService.save(dto);
return "redirect:/";
}
/**
* 검색 form으로 이동
* @return HTML 파일 경로
* */
@GetMapping("select")
public String select() {
return "selectForm";
}
@PostMapping("select")
public String select(@RequestParam("id") String id, Model model) {
PersonDTO dto = personService.select(id);
model.addAttribute("id", id);
model.addAttribute("person", dto);
return "select";
}
}
(2) [src/main/resources] - [templates] 안에 selectForm.html 파일 생성 후 아래와 같이 작성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>검색</title>
</head>
<body>
<h1>[ 검색 ]</h1>
<form action="select" method="post">
검색할 아이디 <input type="text" name="id"><br>
<input type="submit" value="검색"><br>
</form>
</body>
</html>
(3) [src/main/java] - [net.datasa.web3] 안에 PersonService.java 파일 생성 후 아래와 같이 작성
package net.datasa.web3;
//import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Service
@Transactional
public class PersonService {
// 이렇게 작성해도 되지만 아래의 방식이 더 권장된다!
// @Autowired
// PersonRepository PersonRepository;
private final PersonRepository personRepository;
public void test() {
PersonEntity entity = new PersonEntity();
entity.setId("abcde2");
entity.setName("김길동");
entity.setAge(22);
personRepository.save(entity);
}
public void save(PersonDTO dto) {
PersonEntity entity = new PersonEntity();
entity.setId(dto.getId());
entity.setName(dto.getName());
entity.setAge(dto.getAge());
personRepository.save(entity);
}
public PersonDTO select(String id) {
// findById() : Primary Key 기준으로 검색을 하는 메서드
// orElse(null) : 결과가 없으면 "null" 값을 대입하는 메서드
PersonEntity entity = personRepository.findById(id).orElse(null);
if (entity == null) {
return null;
}
PersonDTO dto = new PersonDTO();
dto.setId(entity.getId());
dto.setName(entity.getName());
dto.setAge(entity.getAge());
return dto;
}
}
(4) [src/main/resources] - [templates] 안에 select.html 파일 생성 후 아래와 같이 작성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>검색 결과</title>
</head>
<body>
<h1>[ 검색 결과 ]</h1>
<!--
abc : 없는 ID입니다.
-->
<!--
아이디 : abc
이름 : 홍길동
나이 : 20
-->
<div th:if="${person == null}">
<!--
이렇게 작성해도 아래 element 출력 결과와 동일함
<p th:text="${id} + ' : 없는 ID입니다.'"></p>
-->
<p><span th:text="${id}"></span> : 없는 ID입니다.</p>
</div>
<div th:if="${person != null}">
<p>아이디 : <span th:text="${person.id}"></span></p>
<p>이름 : <span th:text="${person.name}"></span></p>
<p>나이 : <span th:text="${person.age}"></span></p>
</div>
<hr>
<br>
<!-- 위의 아이디, 이름, 나이 출력부분을 다른 방법으로 표현함(th:object 사용) -->
<!--
<div th:if="${person != null}">
<div th:object="${person}">
<p>아이디* : <span th:text="*{id}"></span></p>
<p>이름* : <span th:text="*{name}"></span></p>
<p>나이* : <span th:text="*{age}"></span></p>
</div>
</div>
-->
<!--
<p><span>id : </span>[[${id}]]</p>
<p><span>person : </span>[[${person}]]</p>
-->
</body>
</html>
(5) 결과 화면
첫 접속 화면
"사용자 정보 조회" 문구 클릭 시 화면
검색할 아이디 입력 후 "검색" 버튼 클릭 시 화면(검색한 아이디가 존재할 경우, 아이디가 존재하지 않을 경우)
1-2) 추가 정리사항
DB와 연결하기 위해
runtimeOnly 'com.mysql:mysql-connector-j'를
build.gradle 파일의 "dependencies"에 드라이버로서 추가한다!
application.properties 파일에
spring.jpa.hibernate.ddl-auto=create를 추가하면
Entity를 추가할 때 새로 만들어주기 때문에 문제가 발생해서 잘 사용하지 않는다!
(“create”를 사용하게 되면 기존의 Entity를 지우고 새로 만들기 때문에 기존의 데이터가 전부 사라져서 문제가 발생한다!)
DTO : 사용자 입장에 맞춰서 만든다!
Entity : DB 쪽에 맞춰서 만든다!
DML 명령어 중 하나라도 에러가 있으면 연관된 DML 전부를 취소해서 원래대로 RollBack해야 한다!
(@Transactional annotation을 사용해서 해당 작업을 RollBack할 수 있음)
저장, 수정, 삭제에 해당하는 명령어는 반드시 “Commit”해야지만 DB에 반영된다!
JPA : DB는 SQL 명령어밖에 인식할 수 없기 때문에 이때 Java로 명령을 동적으로 내려야 하는데
이렇게 Java 명령을 동적으로 만들어주는 역할을 하는 것이 “JPA”이다!
Table의 행 하나하나가 “Entity”이다!