ݺߣ

ݺߣShare a Scribd company logo
JPA 잘 (하는 척) 하기
SLiPP-JPA 이경원
목차
● JPA 소개
● JDBC부터 JPA까지
● 객체와 테이블
● 엔티티 생명주기
● 영속성 컨텍스트
● Spring Data JPA
● 참고 자료
● QnA
JPA(Java Persistence API) 소개
● Java ORM(Object-Relational Mapping) 표준 F/W
● RDB를 객체로 표현(매핑), 사용
● Hibernate, Eclipse Link, TopLink Essensials 구현체
JDBC부터 JPA까지
요구 사항
단순 CRU(입력, 조회, 수정)
public class User {
private int userId;
private String name;
private String password;
}
JDBC
// connection…
1. 쿼리 생성
String insertQuery = "insert into User(userId, name, password) values(?, ?, ?)";
2. parameter 매핑
pstmt.setInt(1, user.getUserId());
pstmt.setString(2, user.getName());
pstmt.setString(3, user.getPassword());
3. 쿼리 실행
pstmt.executeUpdate(insertQuery);
// close...
// connection…
1. 쿼리 생성
String selectQuery = "select userId, name, password from User where userId =" +
user.getUserId();
2. 쿼리 실행
ResultSet rs = stmt.executeQuery(selectQuery);
3. 데이터 매핑
user.setUserId(rs.getInt("userId"));
user.setName(rs.getString("name"));
user.setPassword(rs.getString("password"));
// close...
// connection…
1. 쿼리 생성
String updateQuery = "update User set name = ?, password = ? where userId = ?";
2. parameter 매핑
pstmt.setString(1, user.getName());
pstmt.setString(2, user.getPassword());
pstmt.setInt(3, user.getUserId());
3. 쿼리 실행
pstmt.executeUpdate(updateQuery);
// close...
Query 생성, 실행, 데이터 매핑 반복
Connection, close 코드 반복
MyBatis
1. insert
<insert id="inser" parameterType="User">
insert into User(userId, name, password) values (#{userId}, #{name}, #{password})
</insert>
2. select
<select id="select" parameterType="java.lang.Integer" resultType="User">
select userId, name, password from User where userId = #{userId}
</select>
3. update
<update id="update" parameterType="User">
update User set name = #{name}, password = #{password} where userId = #{userId}
</update>
Connection, close 위임
parameter 매핑, 데이터 매핑 위임
하지만 여전히 Query 작성 반복
JPA
EntityManager em = entityManagerFactory.createEntityManager();
// Insert
em.persist(user);
// Select
User user = em.find(User.class, user.getUserId());
// Update
user.setName("update Name");
user.setPassword("1111");
// Delete
em.remove(user);
Connection, close 위임
쿼리 자동 생성, 실행
User 테이블에
“nickName” 컬럼이 추가 된다면?
public class User {
private int userId;
private String name;
private String password;
// nickName 컬럼 추가
private String nickName;
}
JDBC
1. insert 쿼리 생성
String insertQuery = "insert into User(userId, name, password, nickName) values(?, ?, ?, ?)";
2. parameter 매핑
pstmt.setInt(1, user.getUserId());
pstmt.setString(2, user.getName());
pstmt.setString(3, user.getPassword());
pstmt.setString(4, user.getNickName());
3. 쿼리 실행
pstmt.executeUpdate(insertQuery);
1. select 쿼리 생성
String selectQuery = "select userId, name, password, nickname from User where userId = " +
user.getUserId();
2. 쿼리 실행
ResultSet rs = stmt.executeQuery(selectQuery);
3. 데이터 매핑
user.setUserId(rs.getInt("userId"));
user.setName(rs.getString("name"));
user.setPassword(rs.getString("password"));
user.setNickName(rs.getString("nickName"));
1. update 쿼리 생성
String updateQuery = "update User set name = ?, password = ?, nickName = ? where userId =
?";
2. parameter 매핑
pstmt.setString(1, user.getName());
pstmt.setString(2, user.getPassword());
pstmt.setString(3, user.getNickName());
pstmt.setInt(4, user.getUserId());
3. 쿼리 실행
pstmt.executeUpdate(updateQuery);
Query 수정, 데이터 매핑 코드 추가
MyBatis
1. insert
<insert id="inser" parameterType="User">
insert into User(userId, name, password, nickName)
values (#{userId}, #{name}, #{password}, #{nickName})
</insert>
2. select
<select id="select" parameterType="java.lang.Integer" resultType="User">
select userId, name, password, nickName from User where userId = #{userId}
</select>
3. update
<update id="update" parameterType="User">
update User set name = #{name}, password = #{password}, nickName = #{nickName}
where userId = #{userId}
</update>
Query 수정
JPA는 얼마나 변경됐을까요?
// insert
em.persist(user);
// select
em.find(User.class, user.getUserId());
// update
user.setName("update Name");
user.setPassword("1111");
// delete
em.remove(user);
// insert
em.persist(user);
// select
em.find(User.class, user.getUserId());
// update
user.setName("update Name");
user.setPassword("1111");
user.setNickName("update nickName");
// delete
em.remove(user);
요구사항 변경 전 요구사항 변경 후
모든 Domain은 변경된다.
● type safe 하지 않고
● 실수할 확률이 높고
● 수정해야 할 코드가 많아지며
● 단순 CRUD 코드를 반복한다.
객체와 테이블
테이블 지향 엔티티
public class User {
private int userId;
private String name;
private String password;
private String nickName;
}
public class Board {
private int boardId;
// foreign key
private int userId;
private String title;
private String content;
}
객체 지향 엔티티
public class User {
private int userId;
private String name;
private String password;
private String nickName;
}
public class Board {
private int boardId;
// object reference
private User user;
private String title;
private String content;
}
● 객체 그래프 탐색
● 테이블과 객체 간 연관 관계 불일치
● Query 작성 증가
엔티티 생명주기
● New(비영속) : DB에 반영 되지 않고 영속성 컨텍스트와 관
계 없는 엔티티
● Managed(영속) : 영속성 컨텍스트에 저장된 엔티티
● Detached(준영속) : 영속성 컨텍스트에서 분리된 엔티티
● Removed(삭제) : 삭제된 엔티티
Jpa 잘 (하는 척) 하기
비영속 그리고 준영속
// 비 영속
User newUser = new User(“name”, “password”, “nickName”);
// 준 영속
User detachUser = new User(1, “name”, “password”, “nickName”);
detachUser.userId가
DB에 있는 경우 ‵Ӥ영속”
영속성 컨텍스트
● 쓰기 지연 SQL
● 자동 변경 감지
● 1차 캐시
● 엔티티 동일성
● 지연 로딩
영속성 컨텍스트는 어떻게 동까?
@Entity
@Table(name = "User")
public class User {
@Id @GeneratedValue
private Integer userId;
@Column(name = "name", nullable = true)
private String name;
@Column(name = "password", nullable = true)
private String password;
@Column(name = "nickName", nullable = true)
private String nickName;
}
입력()
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// 비 영속 상태
User user = new User("wons", "12345", "woniper");
// 영속 상태
// 1차 캐시 저장
em.persist(user);
// 준영속 상태
// SQL 저장소 쿼리 반영
em.getTransaction().commit();
em.close();
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기
조회(ھԻ)
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// 영속 엔티티
// 1차 캐시 저장
User user = em.find(User.class, user.getUserId());
// 준영속 상태
em.getTransaction().commit();
em.close();
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기
수정(자동 변경 감지)
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// 영속 상태
// 1차 캐시 저장
User user = em.find(User.class, user.getUserId());
// 자동 변경 감지
user.setName("updateName");
user.setPassword("1111");
user.setNickName("updateNick");
// 준영속 상태
// SQL 저장소 쿼리 반영
em.getTransaction().commit();
em.close();
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기
삭제(𳾴DZ)
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// 영속 상태, 1차 캐시 저장
User user = em.find(User.class, user.getUserId());
// 삭제 상태
em.remove(user);
// SQL 저장소 쿼리 반영
em.getTransaction().commit();
em.close();
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기
지금까지 모든 일은 트랜젝션
작업 단위에서 동작
사실 commit은
EntityManager.flush()를 먼저 ˳출
flush()는 영속성 컨텍스트와 DB를 동기화
merge
준 영속 엔티티 -> 영속 엔티티
merge를 알아보기 전에
영속 엔티티 -> 준 영속 엔티티
● em.clear();
● em.detach(user);
● em.getTransaction().commit();
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// 1. 영속 상태
User user1 = em.find(User.class, 1);
// 2. 준영속 상태
em.detach(user1);
// 3. name 속성 변경
user1.setName("lee-kyung-won");
// 4. 영속 상태
em.merge(user1);
em.getTransaction().commit();
em.close();
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// 5. name 속성 값은?
User user2 = em.find(User.class, 1);
em.getTransaction().commit();
em.close();
● 속성이 변경된 준영속 엔티티 merge : update
● 비영속 엔티티 merge : insert
즉 merge는 영속 엔티티로 만들기도 하지
만
update 또는 insert 하기도 함
준 영속 상태는 영속성 컨텍스트
특징을 사용하지 못하는 것
● 쓰기 지연 SQL
● 자동 변경 감지
● 1차 캐시
● 엔티티 동일성
● 지연 로딩
Spring Data JPA
소개 정도만 할게요.
@Entity
@Table(name = "User")
public class User {
@Id @GeneratedValue
private Integer userId;
@Column(name = "name", nullable = true)
private String name;
@Column(name = "password", nullable = true)
private String password;
@Column(name = "nickName", nullable = true)
private String nickName;
}
Repository Interface
public interface UserRepository extends JpaRepository<User, Integer> {
}
Repository 만 추가 면
● save(T);
● delete(T);
● findOne(ID);
● findAll();
● findAll(Pageable);
CRUD 그 외 조회 Query가
필요하다면?
Query Method
http://goo.gl/luWvvP
method 이름으로 Query생성
정확히 말면 JPQL 생성
물론 규칙을 지켜 method 이름 설정
public interface UserRepository extends JpaRepository<User, Integer> {
// where u.name = ?name
User findByName(String name);
// where u.name = ?name and u.password = ?password;
User findByNameAndPassword(String name, String password);
}
참고자료
Jpa 잘 (하는 척) 하기
● http://www.tutorialspoint.com/jpa/
● http://www.objectdb.com/
● https://en.wikibooks.
org/wiki/Java_Persistence
● http://goo.gl/xzpTdK
● https://goo.gl/sqmO9p
● https://goo.gl/GhsI4Q
● https://goo.gl/GpQzeL
QnA
● blog : http://blog.woniper.net
● github : https://github.com/woniper
● email : leekw3747@gmail.com
Ad

Recommended

[수정본] 우아한 객체지향
[수정본] 우아한 객체지향
Young-Ho Cho
DDD 구현기초 (거의 Final 버전)
DDD 구현기초 (거의 Final 버전)
beom kyun choi
도메인 주도 설계의 본질
도메인 주도 설계의 본질
Young-Ho Cho
객체지향적인 도메인 레이어 구축하기
객체지향적인 도메인 레이어 구축하기
Young-Ho Cho
Ksug2015 - JPA2, JPA 기초와매핑
Ksug2015 - JPA2, JPA 기초와매핑
Younghan Kim
Ksug2015 - JPA3, JPA 내부구조
Ksug2015 - JPA3, JPA 내부구조
Younghan Kim
Spring boot Introduction
Spring boot Introduction
Jeevesh Pandey
스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해
beom kyun choi
jpa-hibernate-presentation
jpa-hibernate-presentation
John Slick
Introduction à spring boot
Antoine Rey
Spring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutes
VMware Tanzu
Spring data jpa
Spring data jpa
Jeevesh Pandey
react redux.pdf
react redux.pdf
Knoldus Inc.
Hibernate Presentation
Hibernate Presentation
guest11106b
애플리케이션 아키텍처와 객체지향
애플리케이션 아키텍처와 객체지향
Young-Ho Cho
React + Redux Introduction
React + Redux Introduction
Nikolaus Graf
영속성 컨텍스트로 보는 JPA
영속성 컨텍스트로 보는 JPA
경원 이
Hibernate architecture
Hibernate architecture
Anurag
Spring Core
Spring Core
Pushan Bhattacharya
Node.js Express
Node.js Express
Eyal Vardi
Introduction to JWT and How to integrate with Spring Security
Introduction to JWT and How to integrate with Spring Security
Bruno Henrique Rother
Mongoose and MongoDB 101
Mongoose and MongoDB 101
Will Button
Spring boot
Spring boot
sdeeg
우아테크세미나-우아멀티모듈
우아테크세미나-우아멀티모듈
용근 권
Java 8-streams-collectors-patterns
José Paumard
우아한 객체지향
우아한 객체지향
Young-Ho Cho
Java Hibernate Programming with Architecture Diagram and Example
Java Hibernate Programming with Architecture Diagram and Example
kamal kotecha
[2018] MyBatis에서 JPA로
[2018] MyBatis에서 JPA로
NHN FORWARD
MyBatis에서 JPA로
MyBatis에서 JPA로
Dongmin Shin

More Related Content

What's hot (20)

jpa-hibernate-presentation
jpa-hibernate-presentation
John Slick
Introduction à spring boot
Antoine Rey
Spring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutes
VMware Tanzu
Spring data jpa
Spring data jpa
Jeevesh Pandey
react redux.pdf
react redux.pdf
Knoldus Inc.
Hibernate Presentation
Hibernate Presentation
guest11106b
애플리케이션 아키텍처와 객체지향
애플리케이션 아키텍처와 객체지향
Young-Ho Cho
React + Redux Introduction
React + Redux Introduction
Nikolaus Graf
영속성 컨텍스트로 보는 JPA
영속성 컨텍스트로 보는 JPA
경원 이
Hibernate architecture
Hibernate architecture
Anurag
Spring Core
Spring Core
Pushan Bhattacharya
Node.js Express
Node.js Express
Eyal Vardi
Introduction to JWT and How to integrate with Spring Security
Introduction to JWT and How to integrate with Spring Security
Bruno Henrique Rother
Mongoose and MongoDB 101
Mongoose and MongoDB 101
Will Button
Spring boot
Spring boot
sdeeg
우아테크세미나-우아멀티모듈
우아테크세미나-우아멀티모듈
용근 권
Java 8-streams-collectors-patterns
José Paumard
우아한 객체지향
우아한 객체지향
Young-Ho Cho
Java Hibernate Programming with Architecture Diagram and Example
Java Hibernate Programming with Architecture Diagram and Example
kamal kotecha
jpa-hibernate-presentation
jpa-hibernate-presentation
John Slick
Introduction à spring boot
Antoine Rey
Spring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutes
VMware Tanzu
Hibernate Presentation
Hibernate Presentation
guest11106b
애플리케이션 아키텍처와 객체지향
애플리케이션 아키텍처와 객체지향
Young-Ho Cho
React + Redux Introduction
React + Redux Introduction
Nikolaus Graf
영속성 컨텍스트로 보는 JPA
영속성 컨텍스트로 보는 JPA
경원 이
Hibernate architecture
Hibernate architecture
Anurag
Introduction to JWT and How to integrate with Spring Security
Introduction to JWT and How to integrate with Spring Security
Bruno Henrique Rother
Mongoose and MongoDB 101
Mongoose and MongoDB 101
Will Button
Spring boot
Spring boot
sdeeg
우아테크세미나-우아멀티모듈
우아테크세미나-우아멀티모듈
용근 권
Java 8-streams-collectors-patterns
José Paumard
Java Hibernate Programming with Architecture Diagram and Example
Java Hibernate Programming with Architecture Diagram and Example
kamal kotecha

Similar to Jpa 잘 (하는 척) 하기 (20)

[2018] MyBatis에서 JPA로
[2018] MyBatis에서 JPA로
NHN FORWARD
MyBatis에서 JPA로
MyBatis에서 JPA로
Dongmin Shin
#16.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#16.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
탑크리에듀(구로디지털단지역3번출구 2분거리)
[162] jpa와 모던 자바 데이터 저장 기술
[162] jpa와 모던 자바 데이터 저장 기술
NAVER D2
Ksug2015 - JPA1, JPA 소개
Ksug2015 - JPA1, JPA 소개
Younghan Kim
Java Annotation과 MyBatis로 나만의 ORM Framework을 만들어보자
Java Annotation과 MyBatis로 나만의 ORM Framework을 만들어보자
Donghyeok Kang
Ksug2015 jpa5 스프링과jpa
Ksug2015 jpa5 스프링과jpa
Younghan Kim
Spring data jpa
Spring data jpa
Taesin Um
SpringDataJPA - 스프링 캠프
SpringDataJPA - 스프링 캠프
Younghan Kim
Jpa 필드 와 컬럼 매핑 레퍼런스
Jpa 필드 와 컬럼 매핑 레퍼런스
Jong Woo Rhee
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
탑크리에듀(구로디지털단지역3번출구 2분거리)
JPA 관련 스터디내용입니다. 천천히 다가가기천천히 다가가기천천히 다가가기천천히 다가가기
JPA 관련 스터디내용입니다. 천천히 다가가기천천히 다가가기천천히 다가가기천천히 다가가기
Jeong-gyu Kim
Daejeon IT Developer Conference Hibernate3
Daejeon IT Developer Conference Hibernate3
plusperson
Daejeon IT Developer Conference Hibernate3
Daejeon IT Developer Conference Hibernate3
plusperson
자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)
자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)
DK Lee
JPA Study - 1주차(SLIPP)
JPA Study - 1주차(SLIPP)
Jeong-gyu Kim
#17.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#17.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
탑크리에듀(구로디지털단지역3번출구 2분거리)
Ksug2015 jpa4 객체지향쿼리
Ksug2015 jpa4 객체지향쿼리
Younghan Kim
Jpa 쿼리 포함 자료
Jpa 쿼리 포함 자료
Hyosang Hong
Jpa 쿼리 포함 자료
Jpa 쿼리 포함 자료
Hyosang Hong
[2018] MyBatis에서 JPA로
[2018] MyBatis에서 JPA로
NHN FORWARD
#16.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#16.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
탑크리에듀(구로디지털단지역3번출구 2분거리)
[162] jpa와 모던 자바 데이터 저장 기술
[162] jpa와 모던 자바 데이터 저장 기술
NAVER D2
Ksug2015 - JPA1, JPA 소개
Ksug2015 - JPA1, JPA 소개
Younghan Kim
Java Annotation과 MyBatis로 나만의 ORM Framework을 만들어보자
Java Annotation과 MyBatis로 나만의 ORM Framework을 만들어보자
Donghyeok Kang
Ksug2015 jpa5 스프링과jpa
Ksug2015 jpa5 스프링과jpa
Younghan Kim
SpringDataJPA - 스프링 캠프
SpringDataJPA - 스프링 캠프
Younghan Kim
Jpa 필드 와 컬럼 매핑 레퍼런스
Jpa 필드 와 컬럼 매핑 레퍼런스
Jong Woo Rhee
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
탑크리에듀(구로디지털단지역3번출구 2분거리)
JPA 관련 스터디내용입니다. 천천히 다가가기천천히 다가가기천천히 다가가기천천히 다가가기
JPA 관련 스터디내용입니다. 천천히 다가가기천천히 다가가기천천히 다가가기천천히 다가가기
Jeong-gyu Kim
Daejeon IT Developer Conference Hibernate3
Daejeon IT Developer Conference Hibernate3
plusperson
Daejeon IT Developer Conference Hibernate3
Daejeon IT Developer Conference Hibernate3
plusperson
자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)
자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)
DK Lee
JPA Study - 1주차(SLIPP)
JPA Study - 1주차(SLIPP)
Jeong-gyu Kim
#17.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#17.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
탑크리에듀(구로디지털단지역3번출구 2분거리)
Ksug2015 jpa4 객체지향쿼리
Ksug2015 jpa4 객체지향쿼리
Younghan Kim
Jpa 쿼리 포함 자료
Jpa 쿼리 포함 자료
Hyosang Hong
Jpa 쿼리 포함 자료
Jpa 쿼리 포함 자료
Hyosang Hong
Ad

Jpa 잘 (하는 척) 하기

  • 1. JPA 잘 (하는 척) 하기 SLiPP-JPA 이경원
  • 2. 목차 ● JPA 소개 ● JDBC부터 JPA까지 ● 객체와 테이블 ● 엔티티 생명주기 ● 영속성 컨텍스트 ● Spring Data JPA ● 참고 자료 ● QnA
  • 4. ● Java ORM(Object-Relational Mapping) 표준 F/W ● RDB를 객체로 표현(매핑), 사용 ● Hibernate, Eclipse Link, TopLink Essensials 구현체
  • 7. 단순 CRU(입력, 조회, 수정) public class User { private int userId; private String name; private String password; }
  • 9. // connection… 1. 쿼리 생성 String insertQuery = "insert into User(userId, name, password) values(?, ?, ?)"; 2. parameter 매핑 pstmt.setInt(1, user.getUserId()); pstmt.setString(2, user.getName()); pstmt.setString(3, user.getPassword()); 3. 쿼리 실행 pstmt.executeUpdate(insertQuery); // close...
  • 10. // connection… 1. 쿼리 생성 String selectQuery = "select userId, name, password from User where userId =" + user.getUserId(); 2. 쿼리 실행 ResultSet rs = stmt.executeQuery(selectQuery); 3. 데이터 매핑 user.setUserId(rs.getInt("userId")); user.setName(rs.getString("name")); user.setPassword(rs.getString("password")); // close...
  • 11. // connection… 1. 쿼리 생성 String updateQuery = "update User set name = ?, password = ? where userId = ?"; 2. parameter 매핑 pstmt.setString(1, user.getName()); pstmt.setString(2, user.getPassword()); pstmt.setInt(3, user.getUserId()); 3. 쿼리 실행 pstmt.executeUpdate(updateQuery); // close...
  • 12. Query 생성, 실행, 데이터 매핑 반복
  • 15. 1. insert <insert id="inser" parameterType="User"> insert into User(userId, name, password) values (#{userId}, #{name}, #{password}) </insert> 2. select <select id="select" parameterType="java.lang.Integer" resultType="User"> select userId, name, password from User where userId = #{userId} </select> 3. update <update id="update" parameterType="User"> update User set name = #{name}, password = #{password} where userId = #{userId} </update>
  • 16. Connection, close 위임 parameter 매핑, 데이터 매핑 위임
  • 17. 하지만 여전히 Query 작성 반복
  • 18. JPA
  • 19. EntityManager em = entityManagerFactory.createEntityManager(); // Insert em.persist(user); // Select User user = em.find(User.class, user.getUserId()); // Update user.setName("update Name"); user.setPassword("1111"); // Delete em.remove(user);
  • 20. Connection, close 위임 쿼리 자동 생성, 실행
  • 22. public class User { private int userId; private String name; private String password; // nickName 컬럼 추가 private String nickName; }
  • 23. JDBC
  • 24. 1. insert 쿼리 생성 String insertQuery = "insert into User(userId, name, password, nickName) values(?, ?, ?, ?)"; 2. parameter 매핑 pstmt.setInt(1, user.getUserId()); pstmt.setString(2, user.getName()); pstmt.setString(3, user.getPassword()); pstmt.setString(4, user.getNickName()); 3. 쿼리 실행 pstmt.executeUpdate(insertQuery);
  • 25. 1. select 쿼리 생성 String selectQuery = "select userId, name, password, nickname from User where userId = " + user.getUserId(); 2. 쿼리 실행 ResultSet rs = stmt.executeQuery(selectQuery); 3. 데이터 매핑 user.setUserId(rs.getInt("userId")); user.setName(rs.getString("name")); user.setPassword(rs.getString("password")); user.setNickName(rs.getString("nickName"));
  • 26. 1. update 쿼리 생성 String updateQuery = "update User set name = ?, password = ?, nickName = ? where userId = ?"; 2. parameter 매핑 pstmt.setString(1, user.getName()); pstmt.setString(2, user.getPassword()); pstmt.setString(3, user.getNickName()); pstmt.setInt(4, user.getUserId()); 3. 쿼리 실행 pstmt.executeUpdate(updateQuery);
  • 27. Query 수정, 데이터 매핑 코드 추가
  • 29. 1. insert <insert id="inser" parameterType="User"> insert into User(userId, name, password, nickName) values (#{userId}, #{name}, #{password}, #{nickName}) </insert> 2. select <select id="select" parameterType="java.lang.Integer" resultType="User"> select userId, name, password, nickName from User where userId = #{userId} </select> 3. update <update id="update" parameterType="User"> update User set name = #{name}, password = #{password}, nickName = #{nickName} where userId = #{userId} </update>
  • 32. // insert em.persist(user); // select em.find(User.class, user.getUserId()); // update user.setName("update Name"); user.setPassword("1111"); // delete em.remove(user); // insert em.persist(user); // select em.find(User.class, user.getUserId()); // update user.setName("update Name"); user.setPassword("1111"); user.setNickName("update nickName"); // delete em.remove(user); 요구사항 변경 전 요구사항 변경 후
  • 34. ● type safe 하지 않고 ● 실수할 확률이 높고 ● 수정해야 할 코드가 많아지며 ● 단순 CRUD 코드를 반복한다.
  • 36. 테이블 지향 엔티티 public class User { private int userId; private String name; private String password; private String nickName; } public class Board { private int boardId; // foreign key private int userId; private String title; private String content; }
  • 37. 객체 지향 엔티티 public class User { private int userId; private String name; private String password; private String nickName; } public class Board { private int boardId; // object reference private User user; private String title; private String content; }
  • 38. ● 객체 그래프 탐색 ● 테이블과 객체 간 연관 관계 불일치 ● Query 작성 증가
  • 40. ● New(비영속) : DB에 반영 되지 않고 영속성 컨텍스트와 관 계 없는 엔티티 ● Managed(영속) : 영속성 컨텍스트에 저장된 엔티티 ● Detached(준영속) : 영속성 컨텍스트에서 분리된 엔티티 ● Removed(삭제) : 삭제된 엔티티
  • 43. // 비 영속 User newUser = new User(“name”, “password”, “nickName”); // 준 영속 User detachUser = new User(1, “name”, “password”, “nickName”);
  • 46. ● 쓰기 지연 SQL ● 자동 변경 감지 ● 1차 캐시 ● 엔티티 동일성 ● 지연 로딩
  • 48. @Entity @Table(name = "User") public class User { @Id @GeneratedValue private Integer userId; @Column(name = "name", nullable = true) private String name; @Column(name = "password", nullable = true) private String password; @Column(name = "nickName", nullable = true) private String nickName; }
  • 50. EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); // 비 영속 상태 User user = new User("wons", "12345", "woniper"); // 영속 상태 // 1차 캐시 저장 em.persist(user); // 준영속 상태 // SQL 저장소 쿼리 반영 em.getTransaction().commit(); em.close();
  • 55. EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); // 영속 엔티티 // 1차 캐시 저장 User user = em.find(User.class, user.getUserId()); // 준영속 상태 em.getTransaction().commit(); em.close();
  • 60. EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); // 영속 상태 // 1차 캐시 저장 User user = em.find(User.class, user.getUserId()); // 자동 변경 감지 user.setName("updateName"); user.setPassword("1111"); user.setNickName("updateNick"); // 준영속 상태 // SQL 저장소 쿼리 반영 em.getTransaction().commit(); em.close();
  • 65. EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); // 영속 상태, 1차 캐시 저장 User user = em.find(User.class, user.getUserId()); // 삭제 상태 em.remove(user); // SQL 저장소 쿼리 반영 em.getTransaction().commit(); em.close();
  • 69. 지금까지 모든 일은 트랜젝션 작업 단위에서 동작
  • 72. merge
  • 73. 준 영속 엔티티 -> 영속 엔티티
  • 75. 영속 엔티티 -> 준 영속 엔티티
  • 76. ● em.clear(); ● em.detach(user); ● em.getTransaction().commit();
  • 77. EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); // 1. 영속 상태 User user1 = em.find(User.class, 1); // 2. 준영속 상태 em.detach(user1); // 3. name 속성 변경 user1.setName("lee-kyung-won"); // 4. 영속 상태 em.merge(user1); em.getTransaction().commit(); em.close();
  • 78. EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); // 5. name 속성 값은? User user2 = em.find(User.class, 1); em.getTransaction().commit(); em.close();
  • 79. ● 속성이 변경된 준영속 엔티티 merge : update ● 비영속 엔티티 merge : insert
  • 80. 즉 merge는 영속 엔티티로 만들기도 하지 만 update 또는 insert 하기도 함
  • 81. 준 영속 상태는 영속성 컨텍스트 특징을 사용하지 못하는 것
  • 82. ● 쓰기 지연 SQL ● 자동 변경 감지 ● 1차 캐시 ● 엔티티 동일성 ● 지연 로딩
  • 85. @Entity @Table(name = "User") public class User { @Id @GeneratedValue private Integer userId; @Column(name = "name", nullable = true) private String name; @Column(name = "password", nullable = true) private String password; @Column(name = "nickName", nullable = true) private String nickName; }
  • 87. public interface UserRepository extends JpaRepository<User, Integer> { }
  • 89. ● save(T); ● delete(T); ● findOne(ID); ● findAll(); ● findAll(Pageable);
  • 90. CRUD 그 외 조회 Query가 필요하다면?
  • 94. 물론 규칙을 지켜 method 이름 설정
  • 95. public interface UserRepository extends JpaRepository<User, Integer> { // where u.name = ?name User findByName(String name); // where u.name = ?name and u.password = ?password; User findByNameAndPassword(String name, String password); }
  • 98. ● http://www.tutorialspoint.com/jpa/ ● http://www.objectdb.com/ ● https://en.wikibooks. org/wiki/Java_Persistence
  • 99. ● http://goo.gl/xzpTdK ● https://goo.gl/sqmO9p ● https://goo.gl/GhsI4Q ● https://goo.gl/GpQzeL
  • 100. QnA
  • 101. ● blog : http://blog.woniper.net ● github : https://github.com/woniper ● email : leekw3747@gmail.com