Sangwon Coding
Spring Boot - JPA 연관관계 설정 본문
MySql Workbench 의 Database 탭의 Reverse Engineer 를 통해 다음과 같이 ERD 생성.
ERD를 완성했으면 Database 탭의 Foward Engineer 를 통해 작업 완료.
JPA 연관관계 설정을 위해 관계 어노테이션 및 쿼리메소드를 사용하였다.
User.java
package com.example.study.model.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity // ==table
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String account;
private String email;
private String phoneNumber;
private LocalDateTime createdAt;
private String createdBy;
private LocalDateTime updatedAt;
private String updatedBy;
// 1 : N
@OneToMany(fetch = FetchType.LAZY , mappedBy = "user")
private List<OrderDetail> orderDetailList;
}
Item.java
package com.example.study.model.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Item {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Integer price;
private String content;
// 1 : N
// LAZY = 지연로딩, EAGER = 즉시로딩
// LAZY = SELECT * FROM item WHERE id = ?
// EAGER = JOIN문 사용, 1:1 에서만 추천
@OneToMany(fetch = FetchType.LAZY , mappedBy = "item")
private List<OrderDetail> orderDetailList;
}
OrderDetail.java
package com.example.study.model.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.persistence.*;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity // order_detail
@ToString(exclude = {"user", "item"}) // 2개의 entity 참조를 해서 상호 참조 방지 (오버플로우 발생)
public class OrderDetail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private LocalDateTime orderAt;
// N : 1
@ManyToOne
private User user; // user_id
// N : 1
@ManyToOne
private Item item;
}
UserRepository.java (인터페이스)
package com.example.study.repository;
import com.example.study.model.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// select * from user where account = ? << test03, test04
Optional<User> findByAccount(String account); // 쿼리메소드 사용
Optional<User> findByEmail(String email); // 쿼리메소드 사용
// select * from user where account = ? and email = ?
Optional<User> findByAccountAndEmail(String account, String email); // 쿼리메소드 사용
}
ItemRepository.java (인터페이스)
package com.example.study.repository;
import com.example.study.model.entity.Item;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ItemRepository extends JpaRepository<Item, Long> {
}
OrderDetailRepository.java (인터페이스)
package com.example.study.repository;
import com.example.study.model.entity.OrderDetail;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface OrderDetailRepository extends JpaRepository<OrderDetail, Long> {
}
UserRepositoryTest.java
package com.example.study.repository;
import com.example.study.StudyApplicationTests;
import com.example.study.model.entity.Item;
import com.example.study.model.entity.User;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import javax.transaction.Transactional;
import java.time.LocalDateTime;
import java.util.Optional;
public class UserRepositoryTest extends StudyApplicationTests {
// Dependency Injection (DI)
@Autowired
private UserRepository userRepository;
@Test
public void create(){
// String sql = insert into user (%s, %s, %d) value (account, email, age);
User user = new User();
user.setAccount("TestUser03");
user.setEmail("TestUser03@gmail.com");
user.setPhoneNumber("010-3333-3333");
user.setCreatedAt(LocalDateTime.now());
user.setCreatedBy("TestUser3");
User newUser = userRepository.save(user);
System.out.println("newUser : " + newUser);
}
@Test
@Transactional
public void read(){
// select * from user where id = ?
Optional<User> user = userRepository.findByAccount("TestUser03");
user.ifPresent(selectUser ->{
selectUser.getOrderDetailList().stream().forEach(detail->{
Item item = detail.getItem();
System.out.println(item);
});
});
}
@Test
public void update(){
Optional<User> user = userRepository.findById(2L);
user.ifPresent(selectUser ->{
selectUser.setAccount("PPPP");
selectUser.setUpdatedAt(LocalDateTime.now());
selectUser.setUpdatedBy("update method()");
userRepository.save(selectUser);
});
}
@Test
@Transactional // 실제로 DB에서 삭제되지 않게함, 단지 Test 이기 때문
public void delete(){
Optional<User> user = userRepository.findById(2L);
Assert.assertTrue(user.isPresent()); // 반드시 위의 값이 존재해야함, true
user.ifPresent(selectUser->{
userRepository.delete(selectUser);
});
Optional<User> deleteUser = userRepository.findById(2L);
if(deleteUser.isPresent()){
System.out.println("데이터 존재 : " + deleteUser.get());
}else{
System.out.println("데이터 삭제 되었음");
}
Assert.assertFalse(deleteUser.isPresent()); // 위의 값이 존재하면 안됨, false
}
}
ItemRepositoryTest.java
package com.example.study.repository;
import com.example.study.StudyApplicationTests;
import com.example.study.model.entity.Item;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Optional;
public class ItemRepositoryTest extends StudyApplicationTests {
@Autowired
private ItemRepository itemRepository;
@Test
public void create(){
Item item = new Item();
item.setName("노트북");
item.setPrice(100000);
item.setContent("삼성 노트북");
Item newItem = itemRepository.save(item);
Assert.assertNotNull(newItem);
}
@Test
public void read(){
Long id = 1L;
Optional<Item> item = itemRepository.findById(id);
Assert.assertTrue(item.isPresent());
}
}
OrderDetailRepositoryTest.java
package com.example.study.repository;
import com.example.study.StudyApplicationTests;
import com.example.study.model.entity.OrderDetail;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class OrderDetailRepositoryTest extends StudyApplicationTests {
@Autowired
private OrderDetailRepository orderDetailRepository;
@Test
public void create(){
OrderDetail orderDetail = new OrderDetail();
/*
orderDetail.setOrderAt(LocalDateTime.now());
orderDetail.setUserId(1L);
orderDetail.setItemId(1L);
*/
OrderDetail newOrderDetail = orderDetailRepository.save(orderDetail);
Assert.assertNotNull(newOrderDetail);
}
}
'Spring > Spring Boot (어드민 페이지)' 카테고리의 다른 글
Spring Boot - Entity 및 Repository 설정 (0) | 2019.12.02 |
---|---|
Spring Boot - 어드민 프로젝트를 위한 ERD 설계 (0) | 2019.11.22 |
Spring Boot - JPA를 이용한 CRUD (0) | 2019.11.21 |
Spring Boot - Entity, Repository (0) | 2019.11.21 |
Spring Boot - Lombok, JPA (0) | 2019.11.19 |
Comments