일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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
- Algorithm
- IT
- 운영체제
- 자바
- c언어
- design pattern
- redis
- 백준
- OS
- mongoDB
- Proxy
- Spring
- 디자인 패턴
- 자료구조
- 네트워크
- JPA
- Kafka
- Java
- Heap
- 알고리즘
- Galera Cluster
- MySQL
- JavaScript
- C
- Data Structure
- 컴퓨터구조
- 파이썬
- react
- spring webflux
- MSA
Archives
- Today
- Total
시냅스
Spring JPA 기본 사용법 정리 본문
JPA, Java Persisitence API
- 자바의 주력 ORM 데이터 접근 기술이다.
- ORM(Object-Relational Mapping) 은 객체와 데이터베이스의 관계를 매핑해주는 도구이다.
- 객체는 객체대로 설계, 데이터베이스는 데이터베이스대로 설계
- => 중간에서 ORM이 맵핑한다.
- 데이터베이스 접근을 프로그래밍 언어의 관점에서 맞출 수 있다.
- SQL 문을 직접 작성하지 않고 엔티티를 객체로 표현할 수 있다.
- 객체를 통해 간접적으로 데이터베이스를 다룬다.
- ORM(Object-Relational Mapping) 은 객체와 데이터베이스의 관계를 매핑해주는 도구이다.
- 대개 Querydsl과 함께 사용한다.
- 주로 hibernate 구현체를 사용한다.
- 1차 캐시와 동일성(identity) 를 보장한다
- 트랜잭션을 지원하는 쓰기 지연(transactional write-behind)
- 지연 로딩(lazy Loading)을 통해 성능 최적화를 할 수 있다.
- 지연 로딩 : 객체가 실제 사용될 때 로딩
- 즉시 로딩 : Join sql로 한 번에 연관된 객체가지 미리 조회
JPA 구동 방식
용례 (Spring) - ORM 매핑
@Data
@Entity
public class Item {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) // db 에서 값 증가
private Long id;
@Column(name = "item_name", length = 10) // 생략 가능
private String itemName;
private Integer price;
private Integer quantity;
public Item() {
}
public Item(String itemName, Integer price, Integer quantity) {
this.itemName = itemName;
this.price = price;
this.quantity = quantity;
}
}
- @Entity : JPA가 인식할 수 있는 객체를 선언
- @Table : 만약 생략한다면 class 이름을 테이블 이름으로 사용한다.
- @Id 테이블의 PK와 해당 필드를 매핑한다.
- @GeneratedValue : PK 생성 값을 데이터베이스에서 생성하는 IDENTITY 방식을 사용한다.
- @Column : 객체의 필드를 테이블의 컬럼과 매핑한다.
- JPA는 카멜케이스를 언더스코어 케이스로 자동 변환 해주므로 생략이 가능하다
용례 (Spring) - insert, update, (단건 다건) 조회
@Repository
@Transactional // jpa는 데이터를 변경할 때 transaction이 필수로 필요하다.
public class JpaItemRepository implements ItemRepository {
private final EntityManager em;
public JpaItemRepository(EntityManager em) {
this.em = em;
}
@Override
public Item save(Item item) {
em.persist(item);
return item;
}
@Override
public void update(Long itemId, ItemUpdateDto updateParam) {
Item findItem = em.find(Item.class, itemId);
findItem.setItemName(updateParam.getItemName());
findItem.setPrice(updateParam.getPrice());
findItem.setQuantity(updateParam.getQuantity());
}
@Override
public Optional<Item> findById(Long id) {
Item item = em.find(Item.class, id);
return Optional.ofNullable(item);
}
@Override
public List<Item> findAll(ItemSearchCond cond) {
String jpql = "select i from Item i";
Integer maxPrice = cond.getMaxPrice();
String itemName = cond.getItemName();
if (StringUtils.hasText(itemName) || maxPrice != null) {
jpql += " where";
}
boolean andFlag = false;
ArrayList<Object> param = new ArrayList<>();
if (StringUtils.hasText(itemName)) {
jpql += " i.itemName like concat('%', :itemName, '%')";
param.add(itemName);
andFlag = true;
}
if (maxPrice != null) {
if (andFlag) {
jpql += " and";
}
jpql += " i.price <= :maxPrice";
param.add(maxPrice);
}
log.info("jpql = {}", jpql);
TypedQuery<Item> query = em.createQuery(jpql, Item.class);
if (StringUtils.hasText(itemName)) {
query.setParameter("itemName", itemName);
}
if (maxPrice != null) {
query.setParameter("maxPrice", maxPrice);
}
return query.getResultList();
}
}
- insert
- em 을 통해 persist라는 함수를 사용하여 insert 할 수 있다.
- update
- find를 통해 객체를 찾은 뒤 객체의 내용이 변경됐다면 update를 실행한다.
- JPA 영속성 컨텍스트를 이용한다.
- 단건 조회
- find에 class와 PK 값을 넣어준다.
- 다건 조회
- jpql을 작성하여 createQuery를 통해 실행하면 query가 나오고, 데이터를 바인딩하면 getResultList로 조회 내용을 받을 수 있다.
Spring 을 쓰지 않는 JPA 용례
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class JpaStudyApplication {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
//트랜잭션 시작
tx.begin();
try {
Member member = new Member();
member.setId(1L);
member.setName("memberA");
// 저장
em.persist(member);
// 조회
Member findMember = em.find(Member.class,1L);
System.out.println("fineMember.id : " + findMember.getId());
System.out.println("fineMember.name : " + findMember.getName());
// 조회 후 수정하면 영속성 컨텍스트에 의해 커밋 시점에 DB에 반영된다.
findMember.setName("memberB");
//삭제
em.remove(findMember);
//commit
tx.commit();
}catch (Exception e) {
tx.rollback();
}finally {
em.close();
}
emf.close();
}
}
- transaction 종료에 대한 여부와 다 쓴 자원은 꼭 close 해야한다.
'Java, Spring > JPA' 카테고리의 다른 글
JPA 상속관계 매핑 정리 (0) | 2022.09.17 |
---|---|
JPA 연관관계 정리 (0) | 2022.09.16 |
JPA 엔티티 매핑 정리 (0) | 2022.09.16 |
JPA 영속성 컨텍스트 정리 (0) | 2022.09.16 |
Spring Data JPA 정리 (0) | 2022.09.03 |
Comments