Tag: JPA

0

JPA - 더티 체킹과 업데이트 그리고 벌크 연산

JPA 에서의 업데이트 - 더티 체킹 Entity 에 대한 더티 체킹 을 통한 업데이트가 이뤄집니다. JPA 에서는 Entity 를 업데이트 하기 위한 메소드가 별도로 존재하지 않습니다. JPA 에서의 업데이트는 엔티티 변경 과 더티 체킹 을 통해 업데이트가 이뤄집니다. JPA 에서 엔티티를 변경하기 위해서는 변경하고자 하는 엔티티를 조회한 후 해당 엔티티의 값을 변경하면 트랜잭션을 커밋할 때 변경 감지(Dirty Checking) 가 동작해서 데이터베이스에 UPDATE SQL 이 실행하는 방식으로 Entity 에 대한 변경을 반영합니다. @Override@Transactionalpublic ItemDto.Response modifyItemPrice(Long id, ItemDto.Request itemDto) { // 1. 변경하고자 하는 Entity 를 조회합니다. Optional<Item> optionalItem = itemRepository.findById(id); if (optionalItem.isPresent()) { Item item = optionalItem.get(); // 2. Entity 의 값을 변경합니다. item.updatePrice(itemDto.getPrice()); return ItemDto.Response.toDto(item); } else { throw new RuntimeException("Item not found"); }} Update 쿼리문 발생update item set item_type_id=?, modified_date=?, name=?, price=?, version=? where id=? and version=? 더티체크를 통한 업데이트의 한계더티 체킹을 통한 업데이트는 변경된 Entity 개수만큼 Update 문을 실행합니다. 그렇기 때문에 변경된 Entity 가 100개라면 100번의 Update 문이 실행되는 문제점이 있습니다.

0

JPA JPQL - Fetch Join

목차 JPA JPQL - Fetch Join JPA JPQL - Projection (Select) JPA JPQL (Java Persistence Query Language) JPA - 객체지향 쿼리 언어 N+1 문제란 ? 데이터 조회를 위해 한번의 쿼리가 발생하지만 연관관계에 의해 연관된 객체 모두를 가져오기 위해 N 번의 쿼리가 발생하는 문제 필요한 데이터 조회를 위해 한번의 Select 쿼리가 발생해 객체를 가져왔지만, 연관관계가 설정된 객체는 Lazy 설정 으로 인해 실제 값이 아닌 Proxy 객체 로 대체하는데 해당 객체에 접근할 경우 실제 데이터를 가져오기 위해 처음에 조회된 데이터 만큼 쿼리가 추가적으로 발생하는 문제 Fetch Join Lazy 설정을 무시하고 연관된 객체를 한번에 가져온다. JPQL 에서는 N + 1 문제를 해결하기 위해 fetch join 을 제공한다. fetch join 을 이용해 JPQL 을 작성하게 되면 Lazy 설정을 무시하고, Order 조회시 Member 객체와 Delivery 객체를 전부 다 가져온다. public List<Order> findAllWithMemberDelivery(){ return em.createQuery( "select o from Order o"+ " join fetch o.member m" + " join fetch o.delivery d", Order.class ).getResultList();}

0

JPA JPQL (Java Persistence Query Language)

목차 JPA JPQL - Fetch Join JPA JPQL - Projection (Select) JPA JPQL (Java Persistence Query Language) JPA - 객체지향 쿼리 언어 JPQL JPQL 은 객체지향 쿼리 언어 로 테이블 을 대상으로 쿼리하는 것이 아니라 엔티티 객체 를 대상으로 쿼리한다.JPQL 은 SQL 을 추상화 해서 특정 데이터 베이스 SQL 에 의존하지 않는다. JPQL 문법 select m from Memeber as m where m.age > 18 Entity 와 속성 은 대소문자 구분 O (Member, age) JPQL 키워드 는 대소문자 구분 X (select, from, where) 엔티티 이름 사용, 테이블 이름이 아님 별칭(alias) 은 필수 (m) TypeQuery, Query 반환 타입 형태에 따라 사용하는 타입이 다르다.

0

JPA JPQL - Projection (Select)

목차 JPA JPQL - Fetch Join JPA JPQL - Projection (Select) JPA JPQL (Java Persistence Query Language) JPA - 객체지향 쿼리 언어 Projection 대상 Entity, 임베디드 타입, 스칼라 타입(숫자, 문자등 기본 타입) // Entity select m from Member m// Entity select m.team from Member m// 임베디드 타입select m.address from Member m// 스칼라 타입select m.username, m.age from Member m

0

JPA - 객체지향 쿼리 언어

목차 JPA JPQL - Fetch Join JPA JPQL - Projection (Select) JPA JPQL (Java Persistence Query Language) JPA - 객체지향 쿼리 언어 객체 지향 쿼리 언어 종류 JPQL JPA Criteria QueryDSL 네이티브 SQL JDBC API 직접 사용, MyBatis, SrpignjdbcTemplate 함께 사용 JPQL JPA 를 사용하면 엔티티 객체 를 중심으로 개발 문제는 검색 쿼리 검색을 할때도 테이블이 나닌 엔티티 객체 를 대상으로 검색 모든 DB 데이터를 객체로 변화해서 검색하는 것은 불가능 애플리케이션이 필요한 데이터만 DB 에서 불러오려면 결국 검색 조건인 포함된 SQL 이 필요 JPA 는 SQL 을 추상화한 JPQL 이라는 객체지향 쿼리 언어 제공 SQL 과 문법 유사, SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 지원 JPQL 은 엔티티 객체를 대상으로 쿼리 SQL 은 데이터 베이스 테이블을 대상으로 쿼리 public class JpaMain { public static void main(String[] ars) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello"); EntityManager em = entityManagerFactory.createEntityManager(); EntityTransaction transaction = em.getTransaction(); transaction.begin(); try { String qlString = "select m from Member m where m.username like '%kim%'"; List<Member> result = em.createQuery(qlString, Member.class) .getResultList(); } catch (Exception e) { transaction.rollback(); } finally { em.close(); } entityManagerFactory.close(); }}

0

JPA Entity - 기본키 매핑

목차 JPA Entity - 테이블 매핑 JPA Entity - Column 매핑 JPA Entity - 기본키 매핑 기본키 매핑 방법 직접 매핑 : @Id 자동 생성 : @GeneratedValue strategy (전략) IDENTITY : 데이터 베이스에 위임 SEQUENCE : 데이터 베이스 스퀀스 오브젝트 사용 TABLE : 키 생성용 테이블 사용, 모든 DB 에서 사용 AUTO : 방언에 따라 자동 지정 IDENTITY 전략 기본키 생성을 데이터 베이스에 위임하는 전략 MySQL, PostgreSQL, SQL Server, DB2 에서 사용한다. IDENTITY 전략 - 문제점 DataBase 에 값이 들어가야 Id 값을 알 수 있다. 영속성 Context 에서 Entity 가 관리 되기 위해서는 PK 값이 반드시 있어야 한다. JPA 는 트랜잭션 COMMIT 시점에 INSERT SQL 실행하지만 IDENTITY 전략은 persist 시점에 실행 후 DB 에서 Id 조회

0

JPA Entity - Column 매핑

목차 JPA Entity - 테이블 매핑 JPA Entity - Column 매핑 JPA Entity - 기본키 매핑 @Column| 이름 | 기능 | 기본 값 ||: ——————————— | :————————————————————————————————————————————————— |: ——- || name | 필드와 매핑할 테이블 컬럼 이름 | 객체의 필드 이름| insertable | 등록 가능 여부 (true : 등록 가능, false : 등록 불가) | True|updatable | 변경 가능 여부 (true : 변경 가능, false : 변경 불가)| nullable (DDL) | null 값 허용 여부를 설정한다. false 일 경우 not null 제약 조건 이 생성된다. || unique (DDL) | 한 컬럼에 대한 Unique 제약 조건 을 설정한다. || columnDefinition (DDL) | 데이터 베이스 컬럼 정보를 직접 줄 수 있다. | 필드의 자바 타입| length (DDL) | 문자열 길이 제약 조건을 생성한다. (String 에서만 사용 가능) | 255| precision (DDL) scale (DDL) | BigDecimal 타입에서 사용한다. precision 은 소수점을 포함한 자릿수를 scale 은 소수의 자릿수다. double 과 float 타입에는 적용되지 않는다. | @Enumerated 자바 Enum Type 을 매핑할 때 사용 value EnumType.ORIGINAL : enum 순서를 데이터 베이스에 저장 (Integer) EnumType.STRING : enum 이름을 데이터 베이스에 저장 (String) EnumType.STRING : enum 이름을 데이터 베이스에 저장 (String) | EnumType.ORIGINAL | --> @Temporal value TemporalType.DATE : 날짜 정보, 데이터 베이스 date 타입과 Mapping TemporalType.TIME : 시간 정보, 데이터 베이스 time 타입과 Mapping TemporalType.TIMESTAMP : 날짜와 시간, 데이터 베이스 timestamp 와 Mapping

0

JPA Entity - 테이블 매핑

목차 JPA Entity - 테이블 매핑 JPA Entity - Column 매핑 JPA Entity - 기본키 매핑 Entity 매핑에 사용하는 어노테이션 객체와 테이블 매핑 : @Entity , @Table 필드와 컬럼 매핑 : @Column 기본 키 매핑 : @Id 연관 관계 매핑 : @ManyToOne, @JoinColumn @Entity JPA 가 관리하는 클래스JPA 를 사용하기 위해서는 반드시 Entity 어노테이션을 붙여줘야 한다. 파라미터가 없는 기본 생성자를 반드시 생성해줘야 한다. final 클래스, enum, interface, inner 클래스 에는 사용이 불가능 하다. 저장할 field 에 final 키워드는 사용이 불가능하다. @Table Table 어노테이션은 Entity 와 매핑할 Database Table 을 지정한다.

0

HttpClient 사용하기 - Multipart Parameter 보내기

HttpClient 사용하기 HttpClient 사용하기 - Paramater 보내기 HttpClient 사용하기 - Multipart Parameter 보내기 HttpClient 사용하기 - Multipart Parameter 보내기 Client가 서버로 파일 을 전송하거나 한번에 여러개의 Form 데이터 를 보내기 위해 사용하는 방식이다. 이미지와 같은 Binary 데이터는 기존 application/x-www-form-urlencoded 나 application/json 과 같은 요청으로 적절치 않아 multipart/form-data 형태의 데이터로 요청을 보낸다. application/x-www-form-urlencoded 는 보내는 Paramater를 encoding 해서 전송한다. 데이터가 영숫자가 아닌 경우 3바이트로 표현하기 때문에 바이너리 파일을 전송할 경우 페이로드를 3배로 만들기 때문에 비효율 적이다. multipart/form-data 의 경우는 전송한 모든 문자를 인코딩하지 않은 형태로 보낸다. 의존성 추가하기// https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmimeimplementation group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.3.4' MultipartEntityBuilder 를 이용해 HttpEntity 객체 생성 MultipartEntityBuilder 를 이용해 쉽게 Text나 파일을 (Key, Value) 형태로 Request Body 에 넣을 수 있다. Text를 보낼때는 addTextBody 메소드를 이용해 값을 넣어주고 이미지나 파일 데이터를 보낼 때는 addBinaryBody 메소드를 이용해 Binary 파일 을 넣어주고 Content Type 으로 MULTIPART_FORM_DATA 를 명시해준다.

0

HttpClient 사용하기 - Paramater 보내기

HttpClient 사용하기 HttpClient 사용하기 - Paramater 보내기 HttpClient 사용하기 - Multipart Parameter 보내기 HttpClient 사용하기 - Paramater 보내기 Client가 서버로 요청과 함께 Paramater를 보내는 방법은 크게 Form 형태의 데이터를 보내는 방법과 JSON 형태의 데이터를 보내는 방법이 있다. 보통 Form 형태의 데이터는 (Key, Value) 형태의 데이터로 Http Body에 넣어서 보내고 JSON 형태의 데이터는 String 형태로 변환해 Http Body에 넣어서 보낸다. Form 형태의 데이터를 보낼 때 Header는 application/x-www-form-urlencoded 로 요청을 보내고 JSON 형태의 데이터를 보낼 때 Header는 application/json 로 요청을 보낸다. Paramater 요청 받을 수 있는 Back-end 코드/test/params 에 들어오는 Http 요청과 함께 오는 Paramater 내용을 찍어주는 로직을 작성해준다. Form 형태의 Paramater를 받을 때는 @RequestParam 을 이용해 데이터를 가져올 수 있다. @PostMapping("/test/params")public ResponseEntity testParams(@RequestParam("name") String name, @RequestParam("nickname") String nickName){ log.info("=========================== start ============================"); log.info("Name : " + name); log.info("Nickname : " + nickName); log.info("============================ end ============================="); return ResponseEntity.ok().build();} 요청시 보내는 Paramater 작성 요청시 보내는 Paramater는 NameValuePair 객체를 이용해 (Key, Value) 형태로 값을 넣어준다. 작성이 완료된 NameValuePair 객체를 이용해 HttpEntity 객체를 생성한다. HttpEntity 객체를 요청 객체 Entity에 넣어서 Http 요청을 보내면 요청시 Paramater도 같이 전달 된다. UrlEncodedFormEntity 를 이용해 만들어진 Entity에 대한 요청은 ContentType 이 application/x-www-form-urlencoded 으로 보내진다. List<NameValuePair> params = new ArrayList<>();params.add(new BasicNameValuePair("name", "test"));params.add(new BasicNameValuePair("nickname", "victor"));// NameValuePair 객체 이용해 HttpEntity 객체를 생성한다.HttpEntity entity = new UrlEncodedFormEntity(params);// 요청 객체에 Entity에 Paramater 넣어주기httpPost.setEntity(entity);

0

JPA - Persist Context (영속성 컨텍스트)

목차 JPA - Entity의 생명주기 JPA - Persist Context (영속성 컨텍스트) Persist Context (영속성 컨텍스트) 란? JPA 가 Entity 를 관리하기 위한 공간, Entity 상태가 Database 에 반영되기 전까지 Entity 의 읽기/쓰기/수정/삭제를 상태 관리한다. EntityManagerFactory 에서 EntityManager 를 생성하고 EntityManager 를 이용해 영속성 컨텍스트에 접근할 수 있다. EntityManager 를 이용해 Entity(데이터)를 저장하거나 조회하면 영속성 컨텍스트에서 해당 Entity 를 관리하게 된다. EntityManager 는 Transaction 단위로 영속성 컨텍스트를 생성하고 지운다. EntityManager 와 영속성 Context가 1:1로 대응이 된다. 영속성 Context는 내부에 1차 cache가 존재하고 (key, value) 형태로 데이터를 관리한다.장점 : buffering이나 Caching을 할 수 있다. @Id Entity Member1 member @Id : Key Entity : 객체 영속성 컨텍스트의 이점

0

JPA 프로그래밍(기본편) 2 - JPA 설정하기

JPA 프로그래밍(기본편) 2 - JPA 설정하기Entity 생성하기Entity 어노테이션을 통해 JPA가 관리하는 객체임을 명시해준다. @Entitypublic class Member { @Id private long id; private String name; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }} EntityManagerFactory 생성하기 JPA를 사용하기 위해 persistence.xml에 JPA 설정 정보를 넣어 줬다. 해당 정보를 사용하기 위해서 EntityManagerFactory를 생성해주도록 한다. EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello"); EntityManager 생성하기EntityManagerFactory를 이용해 EntityManager를 생성해준다.

0

JPA 프로그래밍(기본편) 1 - JPA 설정하기

JPA 프로그래밍(기본편) 1 - JPA 설정하기의존성 추가하기JPA를 사용하기 위해서 JPA를 구현한 hibernate 라이브러리를 사용한다. DB로는 메모리 DB인 H2 DataBase를 사용하도록 한다. <!-- JPA 하이버네이트 --><dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>5.3.10.Final</version></dependency><!-- H2 데이터베이스 --><dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.200</version></dependency> JPA Setting 하기resource/META-INF/persistence.xml JPA 표준 문법 설정 javax.persistence.jdbc.driver : 사용하고자 하는 DB 드라이버를 설정한다. javax.persistence.jdbc.user : DB에 접근하기 위한 Username javax.persistence.jdbc.password : DB에 접근하기 위한 Password javax.persistence.jdbc.url : 접근하고자 하는 DataBase 경로 hibernate 전용 문법 설정

0

JPA - Entity의 생명주기

목차 JPA - Entity의 생명주기 JPA - Persist Context (영속성 컨텍스트) 엔티티 생명주기비영속 (new/transient) Entity 객체가 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태 Entity 객체가 생성돼 아직 영속성 컨텍스트에 저장되기 전 상태다. // 비영속 상태Member member = new Member();member.setId(101L);member.setName("HelloJPA"); 영속 (managed) Entity 객체가 현재 영속성 컨텍스트에 관리되는 상태

0

JPA 란?

JPA 란?객체를 이용해 DataBase 테이블을 다루기 위해 만들어진 ORM(Object Relation Mapping) 기술