<!-- 회원검색 -->
<h1>JPA2 회원 조회</h1>
<div class="nav">
<form action="/members/search" method="get">
회원검색이름 : <input type="text" name="name" placeholder="회원검색 이름을 입력하세요">
<button type="submit">검색</button>
</form>
</div>
// 회원 검색
@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";
}
//회원검색2
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;
}
//회원조회 2
List<Member> findByName(String searchName);
//회원검색 2
@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;
}
<!-- 두가지로 회원검색 -->
<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>
// 두가지 회원 검색
@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";
}
//두가지회원검색
public List<Member> getListFindByMembers(Member member) {
List<Member> listMember =memberRepository.findByMembers(member.getId(),member.getSal());
System.out.println("MemberService findByListMembers listMember.size()->"+listMember.size());
return listMember;
}
//두가지로 회원조회
List<Member> findByMembers(Long id, Long sal);
// 검색조건으로 입력한 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;
}
@SpringBootTest : 스프링 부트 띄우고 테스트(이게 없으면 @Autowired 다 실패)
반복 가능한 테스트 지원, 각각의 테스트를 실행할 때마다 트랜잭션을 시작하고
테스트가 끝나면 트랜잭션을 강제로 롤백 (이 어노테이션이 테스트 케이스에서 사용될 때만 롤백)
@Rollback(value= false) 써주면 DB에 입력되고
안써주면 TEST만 진행되어짐
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;
//@SpringBootTest : 스프링 부트 띄우고 테스트(이게 없으면 @Autowired 다 실패)
//반복 가능한 테스트 지원, 각각의 테스트를 실행할 때마다 트랜잭션을 시작하고
//* 테스트가 끝나면 트랜잭션을 강제로 롤백 (이 어노테이션이 테스트 케이스에서 사용될 때만 롤백)
import com.oracle.oBootJpa02.domain.Member;
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()->"+member3.getTeam());
}
//맴버조회
@Test
@Rollback(value= false)
public void memberFind() {
//조건
//회원조회->이순신
Long findId = 2L;
//수행
Member member = memberService.findByMember(findId);
//결과
System.out.println("memberServiceTest memberSave member.getName()->"+member.getName());
}
}
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
logging.level:
org.hibernate.SQL: debug # logger를 통해 하이버네이트 실행 SQL
<!DOCTYPE html>
<html>
<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="btn btn-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="btn btn-lg btn-dark" href="/items">상품목록</a>
</p>
<p class="lead">주문기능</p>
<p>
<a class="btn btn-lg btn-info" href="/order">상품주문</a>
<a class="btn btn-lg btn-info" href="/orders">주문내역</a>
</p>
</div>
</body>
</html>
fk있는곳이 owner
- 값 타입은 변경 불가능하게 설계.
- @Setter 를 제거하고, 생성자에서 값을 모두 초기화해서 변경 불가능한 클래스를 만들기 권장
package com.oracle.oBootJpa03.domain;
import lombok.Getter;
/*
* 1. 값 타입은 변경 불가능하게 설계.
* 2. @Setter 를 제거하고, 생성자에서 값을 모두 초기화해서 변경 불가능한 클래스를 만들기 권장
*/
@ToString
@Getter
@Embeddable //임베디드 당하는애
public class Address {
private String city;
private String street;
private String zipcode;
//밖에서 함부로 쓸수 없도록 걸어둠
protected void Address() {
}
//생성자 설정
public Address(String city , String street , String zipcode ) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
}
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;
/*
@author admin
*/
public enum DeliveryStatus {
READY,COMPLETE
}
package com.oracle.oBootJpa03.domain;
public class OrderSearch {
private String memberName; //회원이름
private OrderStatus orderStatus; //주문상태[ORDER,CANCEL]
}
package com.oracle.oBootJpa03.domain;
//주문, 주문취소
public enum OrderStatus {
ORDER,CANCER
}
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
*************시퀸스 설정***********************
@Data
@SequenceGenerator(name = "member3_seq_gen",
sequenceName = "member3_seq_generator" ,
initialValue = 1,
allocationSize = 1)
*************************************
@Getter
@Setter
@Table(name = "member3")
public class Member {
@Id
*****************시퀸스 설정***********************
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "member3_seq_gen" )
*************************************************
@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
@Table(name = "orders") //이름은 예약어는 피해쓰기 **
@Data
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,CANCLE]
@Enumerated(EnumType.STRING) //무조건 String으로 잡기
private OrderStatus status; //상태값저장할때
//==연관 관계 메서드 ==//
public void setMember(Member member) {
this.member = member;
//member.getOrders().
}
}
🔽InheritanceType.SINGLE_TABLE 권장
부모 클래스에 지정 단일 테이블 전략이므로 InheritanceType.SINGLE_TABLE 설정
🔽InheritanceType.TABLE_PER_CLASS
부모 클래스에 지정. 구현 클래스마다 테이블 전략이므로
🔽InheritanceType.JOINED ->이건 잘 사용하지 않음
부모 클래스에 지정. 조인 전략 이므로 InheritanceType.JOINED 설정
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
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "dtype") //구분자
@Getter
@Setter
public abstract class Item { //싱클톤전략이라서 추상클래스
@Id
@Column(name = "item_id")
private Long id;
private String name;
private int price;
private int stockQuantity;
}
▶@DiscriminatorColumn(name = "dtype")
Item 상속
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;
}
Item 상속
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;
}
Item 상속
package com.oracle.oBootJpa03.domain.item;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@DiscriminatorValue("M")
public class Movie extends Item {
private String director;
private String actor;
}
▶DB설정 완료
▶ localhost:8385