[JPA] JavaEE 환경(Spring)에서 JPA 설정 및 CRUD
프로젝트 구조
- DB는 편의상 H2 DB 사용
- 구현체는 Hibernate 사용
- Spring 자체 설정보다는 JPA 설정 예제를 위해 Spring Boot 사용
- Maven 기반 프로젝트
- JPA란 무엇인가? 에 나오는 user, order 테이블을 예제로 사용
JPAConfig.java
- LocalContainerEntityManagerFactoryBean : EntityManagerFactoryBean을 Spring에서 사용하기 위한 클래스
- JpaVendorAdapter : JPA는 여러 구현체가 존재하기 때문에 구현체별 설정을 지원하기 위한 클래스이다. 나는 hibernate를 사용하기 때문에 HibernateJpaVendorAdapter를 사용한다.
@Configuration
@EnableTransactionManagement
public class JPAConfig {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan("net.woniper.jpa.domain");
// persistence 설정
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
properties.setProperty("hibernate.show_sql", "true");
// 각 구현체의 프로퍼티 확장 및 설정
JpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(jpaVendorAdapter);
em.setJpaProperties(properties);
return em;
}
// H2 DB 설정
@Bean(destroyMethod = "shutdown")
public EmbeddedDatabase dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.setName("slipp")
.build();
}
// Transaction 설정
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
}
Entity(Domain)
- JPA에서 Entity는 하나의 테이블 객체를 표현한 것이라고 생각해 된다.
- @Entity가 테이블 정보이며 변수가 필드가 되는 것이다.
@Entity(name = "tbl_user")
public class User {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Integer userId;
private String username;
private String nickName;
private String address;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Order> orders;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Order> getOrders() {
return orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
public int totalPrice() {
int totalPrice = 0;
for (Order order : orders) {
totalPrice += order.getPrice();
}
return totalPrice;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", username='" + username + '\'' +
", nickName='" + nickName + '\'' +
", address='" + address + '\'' +
", orders=" + orders +
'}';
}
}
@Entity(name = "tbl_order")
public class Order {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Integer orderId;
private String orderName;
private String note;
private int price;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "user_id")
private User user;
public Order(String orderName, String note, int price, User user) {
this.orderName = orderName;
this.note = note;
this.price = price;
this.user = user;
}
public Integer getOrderId() {
return orderId;
}
public void setOrderId(Integer orderId) {
this.orderId = orderId;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Order{" +
"orderId=" + orderId +
", orderName='" + orderName + '\'' +
", note='" + note +
'}' + "\n";
}
}
JPACRUDTest.java
- JavaSE 환경에서 JPA 설정 및 CRUD 과 같은 도메인을 예제로 하기 때문에 테스트 소스는 거의 비슷하다.
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SpringBootJpaApplication.class)
@WebAppConfiguration
public class JPACRUDTest {
@PersistenceUnit
private EntityManagerFactory persistenceEntityManager;
@Autowired
private EntityManagerFactory entityManagerFactory;
private EntityManager entityManager;
private User user;
@Test
public void configTest() {
assertNotNull(persistenceEntityManager);
assertNotNull(entityManagerFactory);
}
@Test
public void update() {
// update
User updateUser = entityManager.find(User.class, user.getUserId());
updateUser.setNickName("update nickName");
updateUser.setAddress("update address");
entityManager.merge(updateUser);
// persistence Context Test
assertEquals("update nickName", user.getNickName());
assertEquals("update address", user.getAddress());
// update Tests
assertEquals("update nickName", updateUser.getNickName());
assertEquals("update address", updateUser.getAddress());
}
@Test
public void delete() {
User getUser = entityManager.find(User.class, user.getUserId());
entityManager.remove(getUser);
User deleteUser = entityManager.find(User.class, user.getUserId());
assertNull(deleteUser);
}
@Test
public void select() {
User findUser = entityManager.find(User.class, user.getUserId());
assertEquals(user.getUserId(), findUser.getUserId());
assertEquals(user.getUsername(), findUser.getUsername());
assertEquals(user.getNickName(), findUser.getNickName());
assertEquals(user.getAddress(), findUser.getAddress());
assertEquals(user.totalPrice(), 145);
// order
assertEquals(user.getOrders().size(), 10);
}
@Before
public void setUp() throws Exception {
entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
// fixture
user = new User();
user.setUsername("kyungwon");
user.setNickName("woniper");
user.setAddress("seoul");
List<Order> orders = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Order order = new Order("order" + i, "note" + i, i + 10, user);
entityManager.persist(order);
orders.add(order);
}
user.setOrders(orders);
entityManager.persist(user);
System.out.println("============ fixture ===========\n" + user);
}
@After
public void after() {
entityManager.getTransaction().commit();
entityManager.close();
}
}
'Java 관련 > JPA' 카테고리의 다른 글
JPA에 기반한 비즈니스로직 중심의 S/W 개발 (0) | 2021.11.17 |
---|---|
JPA 요소 (0) | 2021.10.05 |
[JPA] Entity 객체 생명주기(Lifecycle)와 Persistence Context (0) | 2020.09.07 |
[JPA] @ManyToMany, N:M 관계 매핑 (0) | 2020.09.07 |
[JPA] @OneToMany / @ManyToOne, 1:N / N:1 관계 매핑 (0) | 2020.09.07 |
[JPA] @OneToOne, 1:1 관계 매핑 (0) | 2020.09.07 |
[JPA] JavaSE 환경에서 JPA 설정 및 CRUD (0) | 2020.09.07 |
[JPA] JPA란 무엇인가? (0) | 2020.09.07 |