Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 |
Tags
- ORM
- Spring Batch
- JPA mapping
- spring-webmvc #코드읽기
- spring-webmvc
- 코드 리뷰
- Spring Data JPA
- docker
- spring pid
- REST API
- spring-mvc
- 톰캣
- spring camp
- spring boot
- static inner class
- IntelliJ
- Data REST
- spring boot tomcat
- JPA
- Spring
- Spring Data REST
- batch
- spring jpa
- spring batch 코드
- ApplicationPidFileWriter
- 세미나
- SuperTypeToken
- spring bean
- JUnit
- tomcat
- Today
- 1
- Total
- 916,386
woniper
[JPA] JavaEE 환경(Spring)에서 JPA 설정 및 CRUD 본문
- JPA란 무엇인가?
- JavaSE 환경에서 JPA 설정 및 CRUD
- JavaEE 환경(Spring)에서 JPA 설정 및 CRUD
- @OneToOne, 1:1 관계 매핑
- @OneToMany / @ManyToOne, 1:N / N:1 관계 매핑
- @ManyToMany, N:M 관계 매핑
- Entity 객체 생명주기(Lifecycle)와 Persistence Context
프로젝트 구조
- 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(); } }
'Framework' 카테고리의 다른 글
[JPA] @OneToMany / @ManyToOne, 1:N / N:1 관계 매핑 (0) | 2015.05.12 |
---|---|
[JPA] @OneToOne, 1:1 관계 매핑 (0) | 2015.05.12 |
[JPA] JavaSE 환경에서 JPA 설정 및 CRUD (2) | 2015.05.02 |
[JPA] JPA란 무엇인가? (11) | 2015.05.01 |
[MyBatis] Invalid bound statement (not found): 에러 (9) | 2015.04.01 |
- Tag
- javaEE jpa, JPA, spring jpa
0 Comments