https://docs.spring.io/spring-data/jpa/docs/2.7.10/reference/html/#jpa.sample-app.finders.strategies
테이블 생성하는것. 기존에 dto와 같은 역할이지만, 직접 db에 테이블을 생성한다.
pom xml 추가
entity 폴더생성 및 Member1 파일 생성
환경설정 및 기본 파일 설정 추가
# ddl
# create => 엔티티의 정보를 읽어서 테이블 생성, 재구동시 다시 생성(DROP + CREATE)
# update => 엔티티의 정보를 읽어서 변경사항 발생시 생성(CREATE)
# none => ddl 사용하지 않음
# validate => 엔티티와 테이블이 정상 매핑되었는지 확인
spring.jpa.hibernate.ddl-auto=update
@EntityScan(basePackages = {"com.example.entity"}) // 엔티티 위치
public class FirstSpringStudyApplication {
서버 구동 시,
다음과 같이 DB에 새로운 테이블이 추가된 것을 확인 가능함.
(길이값을 따로 설정하지 않을 시 255로 자동 제한)
일종의 매퍼와 같은 것. 하지만 sql문을 사용하지 않고 DB로 데이터를 전송한다.
package com.example.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.example.entity.Member1;
// 엔티티, 엔티티의 기본키타입
@Repository
public interface Member1Repository extends JpaRepository<Member1, String>{
}
@EntityScan(basePackages = {"com.example.entity"}) // 엔티티 위치
@EnableJpaRepositories(basePackages = {"com.example.repository"}) // 저장소 위치
public class FirstSpringStudyApplication {
package com.example.controller;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.bind.annotation.PostMapping;
import com.example.entity.Member1;
import com.example.repository.Member1Repository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
@RequestMapping( value = "/member1")
@RequiredArgsConstructor
public class Member1Controller {
final String format = "Member1Controller => {}";
final Member1Repository m1Repository; // 저장소 객체
@PostMapping(value = "/update.do")
public String updatePOST(@ModelAttribute Member1 member1){
try {
log.info(format, member1.toString());
// 기존 데이터를 읽어서 변경되지 않는 항목을 그대로 유지
Member1 member2 = m1Repository.findById(member1.getId()).orElse(null);
member2.setName(member1.getName());
member2.setAge(member1.getAge());
m1Repository.save(member2); // 변경이 이루어지는 항목들만 따로 적용하기 위함임. (날짜의 경우 그냥 수정하면 없어져버림.)
// (Save가 수정하는 메소드임!)
return "redirect:/member1/selectlist.do";
} catch (Exception e) {
e.printStackTrace();
return "redirect:/home.do";
}
}
@GetMapping(value = "/update.do")
public ModelAndView updateGET(@RequestParam(name = "id") String id) {
Member1 member1 = m1Repository.findById(id).orElse(null);
return new ModelAndView("/member1/update", "member1", member1);
}
@PostMapping(value = "/delete.do")
public String deletePOST(@RequestParam(name = "id") String id) {
try {
m1Repository.delete(null);
return "redirect:/member1/selectlist.do";
} catch (Exception e) {
e.printStackTrace();
return "redirect:/home.do";
}
}
@GetMapping(value = "/selectlist.do")
public ModelAndView selectListGet(){
List<Member1> list = m1Repository.findAll();
return new ModelAndView("/member1/selectlist", "list", list);
}
@GetMapping(value = "/join.do")
public String joinGET(){
return "/member1/join";// templates / member1 / join.html
}
@PostMapping(value="/join.do")
public String joinPOST(@ModelAttribute Member1 member1) {
log.info(format, member1.toString());
m1Repository.save(member1);
return "redirect:/member1/join";
}
}
html 구성
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h3>회원가입(member1)</h3>
<form th:action="@{/member1/join.do}" method="post">
<input type="text" name="id" /><br />
<input type="text" name="pw" value="a" /><br />
<input type="text" name="name" value="b" /><br />
<input type="number" name="age" value="1"/><br />
<input type="submit" value="회원가입" />
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h3>회원목록(member1)</h3>
<a th:href="@{/member1/join.do}">회원가입</a>
<table border="1">
<tbody>
<tr th:each="obj : ${list}">
<td th:text="${obj.id}"></td>
<td th:text="${obj.pw}"></td>
<td th:text="${obj.name}"></td>
<td th:text="${obj.age}"></td>
<td th:text="${obj.regdate}"></td>
<td>
<a th:href="@{/member1/update.do(id=${obj.id})}">수정</a>
<form th:action="@{/member1/delete.do}" method="post">
<input type="hidden" name="id" th:value="${obj.id}" />
<input type="submit" value="삭제" />
</form>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h3>회원정보수정(mem1)</h3>
<form th:action="@{/member1/update.do}" th:object="member1" method="post">
<input type="text" th:field="${member1.id}" readonly/><br />
<input type="text" th:field="${member1.pw}" /><br />
<input type="text" th:field="${member1.name}" /><br />
<input type="number" th:field="${member1.age}" /><br />
<input type="submit" value="수정하기" />
</form>
</body>
</html>