본문 바로가기

SpringBoot

SpringBoot(13) - Server, JPA, DB 예제(form 입력값 저장 / 검색 결과 출력), 추가 정리 사항

728x90
반응형

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 : DBSQL 명령어밖에 인식할 수 없기 때문에 이때 Java로 명령을 동적으로 내려야 하는데

이렇게 Java 명령을 동적으로 만들어주는 역할을 하는 것이 “JPA”이다!

 

Table의 행 하나하나가 Entity이다!