<!DOCTYPE html>
<html xml:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 회원검색 -->
<h1>JPA2 회원 조회</h1>
<div class="nav">
<form action="/members/search" method="get">
회원검색이름 : <input type="text" name="name" placeholder="회원검색 이름을 입력하세요">
<button type="submit">검색</button>
</form>
</div>
<!-- 회원목록 -->
<div class="container">
<div>
<table border="1">
<thead>
<tr>
<th>No</th>
<th>회원이름</th>
<th>팀 이름</th>
</tr>
</thead>
<tbody>
<tr th:each="member : ${memberList}">
<td th:text="${member.id}"></td>
<td><a th:href="@{/memberModifyForm(id=${member.id})}" th:text="${member.name}"></a></td>
<td th:text="${member.team.name}"></td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
package com.oracle.oBootJpa02.controller;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import com.oracle.oBootJpa02.domain.Member;
import com.oracle.oBootJpa02.service.MemberService;
@Controller
public class MemberController {
private static final Logger logger = LoggerFactory.getLogger(MemberController.class);
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
// 회원등록 페이지 이동
@GetMapping(value = "/members/new")
public String createForm() {
System.out.println("MemberController /members/new Start...");
return "/members/createMemberForm";
}
// 회원저장
@PostMapping(value = "/memberSave")
public String memberSave(Member member) {
System.out.println("MemberController /members/save Start...");
System.out.println("member.getTeamname()->"+member.getTeam());
System.out.println("member.getName()->"+member.getName());
memberService.memberSave(member);
System.out.println("MemberController memberSave After");
return "redirect:/";
}
// 회원목록
@GetMapping(value = "/members")
public String listMember(Model model) {
List<Member> memberList = memberService.getListAllMember();
System.out.println("memberList.get(0).getName()->"+memberList.get(0).getName());
System.out.println("memberList.get(0).getTeam().getName()->"+memberList.get(0).getTeam().getName());
System.out.println("MemberController memberList.size()->"+memberList.size());
model.addAttribute("memberList", memberList);
return "members/memberList";
}
// 회원 수정 폼
@GetMapping(value = "/memberModifyForm")
public String memberModify(Long id, Model model) {
System.out.println("MemberController memberModify id->"+id);
Member member = memberService.findByMember(id);
System.out.println("member.getId()->"+member.getId());
System.out.println("member.getName()->"+member.getName());
System.out.println("member.getTeam().getName()->"+member.getTeam().getName());
model.addAttribute("member", member);
return "members/memberModify";
}
// 회원 수정
@PostMapping(value = "/members/memberUpdate")
public String memberUpdate(Member member, Model model) {
System.out.println("MemberController memberUpdate member->"+member);
memberService.memberUpdate(member);
return "redirect:/members";
}
// 회원 검색
@GetMapping(value = "/members/search")
public String search(Member member, Model model) {
System.out.println("/members/search member.getName()->"+member.getName());
List<Member> memberList = memberService.getListSearchMember(member.getName());
System.out.println("/members/search memberList.size()->"+memberList.size());
model.addAttribute("memberList", memberList);
return "members/memberList";
}
}
package com.oracle.oBootJpa02.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.oracle.oBootJpa02.domain.Member;
import com.oracle.oBootJpa02.repository.MemberRepository;
@Service
@Transactional
public class MemberService {
@Autowired
public final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
// 회원등록
public Member memberSave(Member member) {
System.out.println("MemberService memberSave Start...");
System.out.println("MemberService join member.getName()->"+member.getName());
memberRepository.memberSave(member);
System.out.println("MemberRepository memberSave After");
return member;
}
// 회원목록
public List<Member> getListAllMember() {
List<Member> listMember = memberRepository.findAll();
System.out.println("MemberService getListAllMember listMember.size->"+listMember.size());
return listMember;
}
// 회원수정폼
public Member findByMember(Long memberId) {
Member member1 = memberRepository.findByMember(memberId);
System.out.println("MemberService findByMember member1->"+member1);
return member1;
}
// 회원 최종 수정
public void memberUpdate(Member member) {
memberRepository.updateByMember(member);
System.out.println("MemberService updateMember member->"+member);
return;
}
public List<Member> getListSearchMember(String searchName) {
System.out.println("MemberService getListSearchMember Start...");
// String pSearchName = searchName + '%';
System.out.println("MemberService getListSearchMember searchName->"+searchName);
List<Member> listMember = memberRepository.findByName(searchName);
System.out.println("MemberService getListSearchMember listMember.size()->"+listMember.size());
return listMember;
}
}
package com.oracle.oBootJpa02.repository;
import java.util.List;
import com.oracle.oBootJpa02.domain.Member;
public interface MemberRepository {
Member memberSave(Member member);
List<Member> findAll();
Member findByMember(Long memberId);
int updateByMember(Member member);
List<Member> findByName(String searchName);
}
package com.oracle.oBootJpa02.repository;
import java.util.List;
import javax.persistence.EntityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.oracle.oBootJpa02.domain.Member;
import com.oracle.oBootJpa02.domain.Team;
@Repository
public class JpaMemberRepository implements MemberRepository {
private final EntityManager em;
@Autowired
public JpaMemberRepository(EntityManager em) {
this.em = em;
}
// 회원 저장
@Override
public Member memberSave(Member member) {
// 팀 저장
Team team = new Team();
team.setName(member.getTeamname());
// team.setName(member.getTeam().getName()); 될까?
em.persist(team);
// 회원 저장
member.setTeam(team);
em.persist(member);
System.out.println("JpaMemberRepository memberSave");
return member;
}
// 회원 목록
@Override
public List<Member> findAll() {
List<Member> memberList = em.createQuery("select m from Member m", Member.class)
.getResultList();
System.out.println("JpaMemberRepository findAll memberList.size()->"+memberList.size());
return memberList;
}
// 회원 정보 수정 폼
@Override
public Member findByMember(Long memberId) {
Member member = em.find(Member.class, memberId);
return member;
}
// 회원 최종 수정
@Override
public int updateByMember(Member member) {
int result = 0;
System.out.println("JpaMemberRepository updateByMember member.getId()->"+member.getId());
Member member3 = em.find(Member.class, member.getId());
if( member3 != null) {
// 팀 저장
System.out.println("JpaMemberRepository updateByMember member.getTeamid()->"+member.getTeamid());
Team team = em.find(Team.class, member.getTeamid());
if( team != null ) {
System.out.println("JpaMemberRepository updateByMember member.getTeamname()->"+member.getTeamname());
team.setName(member.getTeamname());
em.persist(team);
}
// 회원 저장
System.out.println("JpaMemberRepository updateByMember member.getName()->"+member.getName());
member3.setTeam(team);
member3.setName(member.getName());
em.persist(member3);
result = 1;
} else {
result = 0;
System.out.println("JpaMemberRepository updateByMember No Exist...");
}
return result;
}
// 회원검색
@Override
public List<Member> findByName(String searchName) {
String pSearchName = searchName + '%';
System.out.println("JpaMemberRepository findByName pSearchName->"+pSearchName);
List<Member> memberList = em.createQuery("select m from Member m where name like :name", Member.class)
.setParameter("name", pSearchName).getResultList();
System.out.println("JpaMemberRepository memberList.size()->"+memberList.size());
return memberList;
}
}
<!DOCTYPE html>
<html xml:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 회원검색 -->
<h1>JPA2 회원 조회</h1>
<div class="nav">
<form action="/members/search" method="get">
회원검색이름 : <input type="text" name="name" placeholder="회원검색 이름을 입력하세요">
<button type="submit">검색</button>
</form>
</div>
<!-- 두가지 회원검색 -->
<div class="nav">
<form action="/findByListMembers" method="get">
회원검색 id 큰것: <input type="text" name="id" placeholder="회원검색 id를 입력하세요">
회원검색 급여 큰것: <input type="text" name="sal" placeholder="회원검색 sal을 입력하세요">
<button type="submit">검색</button>
</form>
</div>
<!-- 회원목록 -->
<div class="container">
<div>
<table border="1">
<thead>
<tr>
<th>No</th>
<th>회원이름</th>
<th>팀 이름</th>
</tr>
</thead>
<tbody>
<tr th:each="member : ${memberList}">
<td th:text="${member.id}"></td>
<td><a th:href="@{/memberModifyForm(id=${member.id})}" th:text="${member.name}"></a></td>
<td th:text="${member.team.name}"></td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
package com.oracle.oBootJpa02.controller;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import com.oracle.oBootJpa02.domain.Member;
import com.oracle.oBootJpa02.service.MemberService;
@Controller
public class MemberController {
private static final Logger logger = LoggerFactory.getLogger(MemberController.class);
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
// 회원등록 페이지 이동
@GetMapping(value = "/members/new")
public String createForm() {
System.out.println("MemberController /members/new Start...");
return "/members/createMemberForm";
}
// 회원저장
@PostMapping(value = "/memberSave")
public String memberSave(Member member) {
System.out.println("MemberController /members/save Start...");
System.out.println("member.getTeamname()->"+member.getTeam());
System.out.println("member.getName()->"+member.getName());
memberService.memberSave(member);
System.out.println("MemberController memberSave After");
return "redirect:/";
}
// 회원목록
@GetMapping(value = "/members")
public String listMember(Model model) {
List<Member> memberList = memberService.getListAllMember();
System.out.println("memberList.get(0).getName()->"+memberList.get(0).getName());
System.out.println("memberList.get(0).getTeam().getName()->"+memberList.get(0).getTeam().getName());
System.out.println("MemberController memberList.size()->"+memberList.size());
model.addAttribute("memberList", memberList);
return "members/memberList";
}
// 회원 수정 폼
@GetMapping(value = "/memberModifyForm")
public String memberModify(Long id, Model model) {
System.out.println("MemberController memberModify id->"+id);
Member member = memberService.findByMember(id);
System.out.println("member.getId()->"+member.getId());
System.out.println("member.getName()->"+member.getName());
System.out.println("member.getTeam().getName()->"+member.getTeam().getName());
model.addAttribute("member", member);
return "members/memberModify";
}
// 회원 수정
@PostMapping(value = "/members/memberUpdate")
public String memberUpdate(Member member, Model model) {
System.out.println("MemberController memberUpdate member->"+member);
memberService.memberUpdate(member);
return "redirect:/members";
}
// 회원 검색
@GetMapping(value = "/members/search")
public String search(Member member, Model model) {
System.out.println("/members/search member.getName()->"+member.getName());
List<Member> memberList = memberService.getListSearchMember(member.getName());
System.out.println("/members/search memberList.size()->"+memberList.size());
model.addAttribute("memberList", memberList);
return "members/memberList";
}
// 두가지 회원 검색
@GetMapping(value = "/findByListMembers")
public String findByListMembers(Member member, Model model) {
List<Member> memberList = memberService.getListFindByMembers(member);
System.out.println("memberList.get(0).getName()->"+memberList.get(0).getName());
System.out.println("memberList.get(0).getTeam().getName()->"+memberList.get(0).getTeam().getName());
model.addAttribute("memberList", memberList);
return "members/memberList";
}
}
package com.oracle.oBootJpa02.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.oracle.oBootJpa02.domain.Member;
import com.oracle.oBootJpa02.repository.MemberRepository;
@Service
@Transactional
public class MemberService {
@Autowired
public final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
// 회원등록
public Member memberSave(Member member) {
System.out.println("MemberService memberSave Start...");
System.out.println("MemberService join member.getName()->"+member.getName());
memberRepository.memberSave(member);
System.out.println("MemberRepository memberSave After");
return member;
}
// 회원목록
public List<Member> getListAllMember() {
List<Member> listMember = memberRepository.findAll();
System.out.println("MemberService getListAllMember listMember.size->"+listMember.size());
return listMember;
}
// 회원수정폼
public Member findByMember(Long memberId) {
Member member1 = memberRepository.findByMember(memberId);
System.out.println("MemberService findByMember member1->"+member1);
return member1;
}
// 회원 최종 수정
public void memberUpdate(Member member) {
memberRepository.updateByMember(member);
System.out.println("MemberService updateMember member->"+member);
return;
}
// 회원 검색
public List<Member> getListSearchMember(String searchName) {
System.out.println("MemberService getListSearchMember Start...");
// String pSearchName = searchName + '%';
System.out.println("MemberService getListSearchMember searchName->"+searchName);
List<Member> listMember = memberRepository.findByName(searchName);
System.out.println("MemberService getListSearchMember listMember.size()->"+listMember.size());
return listMember;
}
// 회원 두가지 검색
public List<Member> getListFindByMembers(Member member) {
List<Member> listMember = memberRepository.findByMembers(member.getId(), member.getSal());
System.out.println("MemberService getListFindByMembers listMember.size()->"+listMember.size());
return listMember;
}
}
package com.oracle.oBootJpa02.repository;
import java.util.List;
import com.oracle.oBootJpa02.domain.Member;
public interface MemberRepository {
Member memberSave(Member member);
List<Member> findAll();
Member findByMember(Long memberId);
int updateByMember(Member member);
List<Member> findByName(String searchName);
List<Member> findByMembers(Long id, Long sal);
}
package com.oracle.oBootJpa02.repository;
import java.util.List;
import javax.persistence.EntityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.oracle.oBootJpa02.domain.Member;
import com.oracle.oBootJpa02.domain.Team;
@Repository
public class JpaMemberRepository implements MemberRepository {
private final EntityManager em;
@Autowired
public JpaMemberRepository(EntityManager em) {
this.em = em;
}
// 회원 저장
@Override
public Member memberSave(Member member) {
// 팀 저장
Team team = new Team();
team.setName(member.getTeamname());
// team.setName(member.getTeam().getName()); 될까?
em.persist(team);
// 회원 저장
member.setTeam(team);
em.persist(member);
System.out.println("JpaMemberRepository memberSave");
return member;
}
// 회원 목록
@Override
public List<Member> findAll() {
List<Member> memberList = em.createQuery("select m from Member m", Member.class)
.getResultList();
System.out.println("JpaMemberRepository findAll memberList.size()->"+memberList.size());
return memberList;
}
// 회원 정보 수정 폼
@Override
public Member findByMember(Long memberId) {
Member member = em.find(Member.class, memberId);
return member;
}
// 회원 최종 수정
@Override
public int updateByMember(Member member) {
int result = 0;
System.out.println("JpaMemberRepository updateByMember member.getId()->"+member.getId());
Member member3 = em.find(Member.class, member.getId());
if( member3 != null) {
// 팀 저장
System.out.println("JpaMemberRepository updateByMember member.getTeamid()->"+member.getTeamid());
Team team = em.find(Team.class, member.getTeamid());
if( team != null ) {
System.out.println("JpaMemberRepository updateByMember member.getTeamname()->"+member.getTeamname());
team.setName(member.getTeamname());
em.persist(team);
}
// 회원 저장
System.out.println("JpaMemberRepository updateByMember member.getName()->"+member.getName());
member3.setTeam(team);
member3.setName(member.getName());
em.persist(member3);
result = 1;
} else {
result = 0;
System.out.println("JpaMemberRepository updateByMember No Exist...");
}
return result;
}
// 회원검색
@Override
public List<Member> findByName(String searchName) {
String pSearchName = searchName + '%';
System.out.println("JpaMemberRepository findByName pSearchName->"+pSearchName);
List<Member> memberList = em.createQuery("select m from Member m where name like :name", Member.class)
.setParameter("name", pSearchName).getResultList();
System.out.println("JpaMemberRepository memberList.size()->"+memberList.size());
return memberList;
}
// 검색조건으로 입력한 id 큰거, sal 큰거
@Override
public List<Member> findByMembers(Long pid, Long psal) {
System.out.println("JpaMemberRepository findByMembers id->"+pid);
System.out.println("JpaMemberRepository findByMembers sal->"+psal);
List<Member> memberList = em.createQuery("select m from Member m where id > :id and sal > :sal", Member.class)
.setParameter("id", pid)
.setParameter("sal", psal)
.getResultList();
System.out.println("JpaMemberRepository memberList.size()->"+memberList.size());
return memberList;
}
}
package com.oracle.oBootJpa02;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import com.oracle.oBootJpa02.domain.Member;
// @SpringBootTest : 스프링 부트 띄우고 테스트(이게 없으면 @Autowired 다 실패)
// 반복 가능한 테스트 지원, 각각의 테스트를 실행할 때마다 트랜잭션을 시작하고
//* 테스트가 끝나면 트랜잭션을 강제로 롤백 (이 어노테이션이 테스트 케이스에서 사용될 때만 롤백)
import com.oracle.oBootJpa02.repository.MemberRepository;
import com.oracle.oBootJpa02.service.MemberService;
@SpringBootTest
@Transactional
public class MemberServiceTest {
@Autowired
MemberService memberService;
@Autowired
MemberRepository memberRepository;
@Test
public void memberSave() {
// 조건
// 회원저장
Member member = new Member();
member.setTeamname("고려");
member.setName("강감찬");
// 수행
Member member3 = memberService.memberSave(member);
// 결과
System.out.println("MemberServiceTest memberSave member3.getId()->"+member3.getId());
System.out.println("MemberServiceTest memberSave member3.getName()->"+member3.getName());
System.out.println("MemberServiceTest memberSave member3.getTeam().getName()->"+member3.getTeam().getName());
}
}
run as -> Junit Test
실제 데이터가 들어가면 안되기 때문에 롤백됨
@Rollback(value = false) 추가
package com.oracle.oBootJpa02;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;
import com.oracle.oBootJpa02.domain.Member;
// @SpringBootTest : 스프링 부트 띄우고 테스트(이게 없으면 @Autowired 다 실패)
// 반복 가능한 테스트 지원, 각각의 테스트를 실행할 때마다 트랜잭션을 시작하고
//* 테스트가 끝나면 트랜잭션을 강제로 롤백 (이 어노테이션이 테스트 케이스에서 사용될 때만 롤백)
import com.oracle.oBootJpa02.repository.MemberRepository;
import com.oracle.oBootJpa02.service.MemberService;
@SpringBootTest
@Transactional
public class MemberServiceTest {
@Autowired
MemberService memberService;
@Autowired
MemberRepository memberRepository;
@Test
@Rollback(value = false)
public void memberSave() {
// 조건
// 회원저장
Member member = new Member();
member.setTeamname("고려");
member.setName("강감찬");
// 수행
Member member3 = memberService.memberSave(member);
// 결과
System.out.println("MemberServiceTest memberSave member3.getId()->"+member3.getId());
System.out.println("MemberServiceTest memberSave member3.getName()->"+member3.getName());
System.out.println("MemberServiceTest memberSave member3.getTeam().getName()->"+member3.getTeam().getName());
}
}
DB에 성공적으로 들어감
package com.oracle.oBootJpa02;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;
import com.oracle.oBootJpa02.domain.Member;
// @SpringBootTest : 스프링 부트 띄우고 테스트(이게 없으면 @Autowired 다 실패)
// 반복 가능한 테스트 지원, 각각의 테스트를 실행할 때마다 트랜잭션을 시작하고
//* 테스트가 끝나면 트랜잭션을 강제로 롤백 (이 어노테이션이 테스트 케이스에서 사용될 때만 롤백)
import com.oracle.oBootJpa02.repository.MemberRepository;
import com.oracle.oBootJpa02.service.MemberService;
@SpringBootTest
@Transactional
public class MemberServiceTest {
@Autowired
MemberService memberService;
@Autowired
MemberRepository memberRepository;
@BeforeEach
public void before1() {
System.out.println("Test BeforeEach");
}
@Test
// @Rollback(value = false)
public void memberSave() {
// 조건
// 회원저장
Member member = new Member();
member.setTeamname("고려");
member.setName("강감찬");
// 수행
Member member3 = memberService.memberSave(member);
// 결과
System.out.println("MemberServiceTest memberSave member3.getId()->"+member3.getId());
System.out.println("MemberServiceTest memberSave member3.getName()->"+member3.getName());
System.out.println("MemberServiceTest memberSave member3.getTeam().getName()->"+member3.getTeam().getName());
}
@Test
public void memberFind() {
// 조건
// 회원조회 --> 이순신
Long findID = 2L;
// 수행
Member member = memberService.findByMember(findID);
// 결과
System.out.println("MemberServiceTest memberSave member.getId()->"+member.getId());
System.out.println("MemberServiceTest memberSave member.getName()->"+member.getName());
System.out.println("MemberServiceTest memberSave member.getTeam().getName()->"+member.getTeam().getName());
}
}
👇테스트를 실행할 때마다 실행
@BeforeEach public void before1() { System.out.println("Test BeforeEach"); }
- 메소드 하나만 지정해서 실행도 가능
application.properties 삭제 / tab으로 띄어쓰기
server:
port : 8385
# Oracle Connect
spring:
datasource:
url: jdbc:oracle:thin:@localhost:1521/xe
username: scottjpa
password: tiger
driver-class-name: oracle.jdbc.driver.OracleDriver
# Jpa Setting
jpa:
hibernate:
ddl-auto: none # none create
properties:
hibernate:
show_sql: true # System.out에 하이버네이트 실행 SQL
format_sql: true
<!DOCTYPE html>
<html xml:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div class="container">
<h1>JungChoong SHOP</h1>
<p class="lead">회원 기능</p>
<p>
<a class="btn btn-lg btn-secondary" href="/members/new">회원 가입</a>
<a class="btm btm-lg btn-secondary" href="/members">회원 목록</a>
</p>
<p class="lead">상품 기능</p>
<p>
<a class="btn btn-lg btn-dark" href="/items/new">상품 등록</a>
<a class="btm btm-lg btn-dark" href="/items">상품 목록</a>
</p>
<p class="lead">주문 기능</p>
<p>
<a class="btn btn-lg btn-info" href="/order">상품 주문</a>
<a class="btm btm-lg btn-info" href="/orders">주문 내역</a>
</p>
</div>
</body>
</html>
JPA Type 유형
👇아래참조해 만듦
다른 패키지에서 생성자 못 만듦-protected / 생성자로만 값 세팅
package com.oracle.oBootJpa03.domain;
import javax.persistence.Embeddable;
import lombok.Getter;
/*
* 1. 값 타입은 변경 불가능하게 설계.
* 2. @Setter 를 제거하고, 생성자에서 값을 모두 초기화해서 변경 불가능한 클래스를 만들기 권장
*/
@Getter
// 값 타입을 정의하는 곳에 표시
@Embeddable
public class Address {
private String city;
private String street;
private String zipcode;
protected Address() {
}
public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
}
상태값을 변경할 때
package com.oracle.oBootJpa03.domain;
/**
*
* @author, admin
*/
public enum DeliveryStatus {
READY , COMPLETE
}
결재때 많이씀
package com.oracle.oBootJpa03.domain;
public enum DeliveryStatus3 {
start , middle , end
}
- @Embeddable : 값 타입을 정의하는 곳에 표시
- @Embedded : 값 타입을 사용하는 곳에 표시
- @Enumerated(EnumType.ORDINAL) ❌
-> 중간에 값이 들어가면 고치기 어려움(심각한 문제 발생가능)- @Enumerated(EnumType.STRING) ⭕
-> 상태값을 받아들일때
package com.oracle.oBootJpa03.domain;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import lombok.Data;
@Entity
@Data
public class Delivery {
@Id
@Column(name = "delivery_id")
private Long id;
// 값 타입을 사용하는 곳에 표시
@Embedded
private Address address;
// Must ***
@Enumerated(EnumType.STRING)
private DeliveryStatus status; // READY(준비), COMPLETE(배송)
}
package com.oracle.oBootJpa03.domain;
public enum OrderStatus {
ORDER , CANCEL
}
package com.oracle.oBootJpa03.domain;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class OrderSearch {
private String memberName; // 회원이름
private OrderStatus status; // 주문상태[ORDER, CANCEL]
}
package com.oracle.oBootJpa03.domain;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "member3")
public class Member {
@Id
@Column(name = "member_id")
private Long id;
private String name;
@Embedded
private Address address;
// Order Entity의 member field에 의해서 mapper 당함 --> 읽기 전용
@OneToMany(mappedBy = "member")
private List<Order> orders = new ArrayList<>();
}
package com.oracle.oBootJpa03.domain;
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import lombok.Data;
@Entity
@Data
@Table(name = "orders")
public class Order {
@Id
@Column(name = "order_id")
private Long id;
// Member Entity의 member_id에 의해 연결
@ManyToOne
@JoinColumn(name = "member_id")
private Member member;
// 배송 정보
@OneToOne
@JoinColumn(name = "delivery_id")
private Delivery delivery;
// 주문 시간
private LocalDateTime orderdate;
// 주문 상태[ ORDER / CANCEL ]
@Enumerated(EnumType.STRING)
private OrderStatus status;
//==연관관계 메서드==//
public void setMember(Member member) {
this.member = member;
member.getOrders().add(this);
}
}
@DiscriminatorColumn(name="DTYPE")
-> 부모 클래스에 선언한다. 하위 클래스를 구분하는 용도의 컬럼이다. default = DTYPE
package com.oracle.oBootJpa03.domain.item;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import lombok.Getter;
import lombok.Setter;
@Entity
@DiscriminatorColumn(name = "dtype")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Getter
@Setter
public abstract class Item {
@Id
@Column(name = "item_id")
private Long id;
private String name;
private int price;
private int stockQuantity;
}
package com.oracle.oBootJpa03.domain.item;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import lombok.Getter;
import lombok.Setter;
@Entity
@DiscriminatorValue("A")
@Getter
@Setter
public class Album extends Item {
private String artist;
private String etc;
}
isbn -> 책 코드
@DiscriminatorValue("XXX")
-> 하위 클래스에 선언한다. 엔티티를 저장할 때 슈퍼타입의 구분 컬럼에 저장할 값을 지정한다. 어노테이션을 선언하지 않을 겨우 기본값으로 클래스 이름이 들어간다. 상속관계 매핑 참고
package com.oracle.oBootJpa03.domain.item;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import lombok.Getter;
import lombok.Setter;
@Entity
@DiscriminatorValue("B")
@Getter
@Setter
public class Book extends Item {
private String author;
private String isbn;
}
package com.oracle.oBootJpa03.domain.item;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import lombok.Getter;
import lombok.Setter;
@Entity
@DiscriminatorValue("M")
@Getter
@Setter
public class Movie extends Item {
private String director;
private String actor;
}
- @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
- @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
- @Inheritance(strategy = InheritanceType.JOINED)
👉 권장은 SINGLE_TABLE