[JPA] JavaSE 환경에서 JPA 설정 및 CRUD

2020. 9. 7. 12:43 Java 관련/JPA

프로젝트 구조

  • DB는 편의상 h2 DB 사용
  • 구현체는 Hibernate 사용
  • JPA란 무엇인가? 에 나오는 user, order 테이블을 예제로 사용 

 

META-INF/persistence.xml

  • hibernate.connection.driver_class : DB Driver
  • hibernate.connection.url : DB url 및 DB파일이 저장될 경로(h2 DB에 한함)
  • hibernate.connection.user : username
  • hibernate.show_sql : JPA 내부적으로 사용되는 쿼리를 log로 나타낼지 설정
  • hibernate.hbm2ddl.auto : Entity에 의한 테이블 설정 (create-drop은 프로젝트 실행시 기존 테이블을 삭제하고 다시 생성한다. 즉 테스트하기 위한 초기화)
  • 구현체와 DB 종류별 설정 참고

 

1
2
3
4
5
6
7
8
9
10
11
12
13
<!--?xml version="1.0" encoding="UTF-8"?-->
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">
 
    <persistence-unit name="persistence" transaction-type="RESOURCE_LOCAL">
        <properties>
            <property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
            <property name="hibernate.connection.url" value="jdbc:h2:file:./data/jpa"/>
            <property name="hibernate.connection.user" value="sa"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        </properties>
    </persistence-unit>
</persistence>
cs

 

 

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

  • EntityManager : Entity의 Lifecycle과 persistence context, transaction을 관리한다. 즉 insert, update, delete, select를 할 수 있다.
    • select : find(Class, Object);
    • insert : persist(Object);
    • update : merge(T);
    • delete : remove(Object);
  • EntityManagerFactory : EntityManager를 생성하기 위한 클래스이며 persistence.xml 설정에 기반한다.
public class JPACRUDTest {

    private EntityManager entityManager;
    private EntityManagerFactory entityManagerFactory;
    private User user;

    @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 {
        entityManagerFactory = Persistence.createEntityManagerFactory("persistence");
        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();
        entityManagerFactory.close();
    }
}

 

참고