jpa 잘 (하는 척) 하기
TRANSCRIPT
![Page 1: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/1.jpg)
JPA 잘 (하는 척) 하기
SLiPP-JPA 이경원
![Page 2: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/2.jpg)
목차
● JPA 소개
● JDBC부터 JPA까지
● 객체와 테이블
● 엔티티 생명주기
● 영속성 컨텍스트
● Spring Data JPA
● 참고 자료
● QnA
![Page 3: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/3.jpg)
JPA(Java Persistence API) 소개
![Page 4: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/4.jpg)
● Java ORM(Object-Relational Mapping) 표준 F/W
● RDB를 객체로 표현(매핑), 사용
● Hibernate, Eclipse Link, TopLink Essensials 구현체
![Page 5: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/5.jpg)
JDBC부터 JPA까지
![Page 6: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/6.jpg)
요구 사항
![Page 7: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/7.jpg)
단순 CRU(입력, 조회, 수정)
public class User {
private int userId;
private String name;
private String password;
}
![Page 8: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/8.jpg)
JDBC
![Page 9: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/9.jpg)
// 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...
![Page 10: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/10.jpg)
// 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...
![Page 11: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/11.jpg)
// 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...
![Page 12: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/12.jpg)
Query 생성, 실행, 데이터 매핑 반복
![Page 13: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/13.jpg)
Connection, close 코드 반복
![Page 14: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/14.jpg)
MyBatis
![Page 15: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/15.jpg)
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>
![Page 16: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/16.jpg)
Connection, close 위임
parameter 매핑, 데이터 매핑 위임
![Page 17: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/17.jpg)
하지만 여전히 Query 작성 반복
![Page 18: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/18.jpg)
JPA
![Page 19: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/19.jpg)
EntityManager em = entityManagerFactory.createEntityManager();
// Insertem.persist(user);
// SelectUser user = em.find(User.class, user.getUserId());
// Updateuser.setName("update Name");user.setPassword("1111");
// Deleteem.remove(user);
![Page 20: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/20.jpg)
Connection, close 위임
쿼리 자동 생성, 실행
![Page 21: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/21.jpg)
User 테이블에
“nickName” 컬럼이 추가 된다면?
![Page 22: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/22.jpg)
public class User {
private int userId;
private String name;
private String password;
// nickName 컬럼 추가private String nickName;
}
![Page 23: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/23.jpg)
JDBC
![Page 24: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/24.jpg)
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);
![Page 25: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/25.jpg)
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"));
![Page 26: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/26.jpg)
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);
![Page 27: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/27.jpg)
Query 수정, 데이터 매핑 코드 추가
![Page 28: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/28.jpg)
MyBatis
![Page 29: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/29.jpg)
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>
![Page 30: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/30.jpg)
Query 수정
![Page 31: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/31.jpg)
JPA는 얼마나 변경됐을까요?
![Page 32: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/32.jpg)
// insertem.persist(user);
// selectem.find(User.class, user.getUserId());
// updateuser.setName("update Name");user.setPassword("1111");
// deleteem.remove(user);
// insertem.persist(user);
// selectem.find(User.class, user.getUserId());
// updateuser.setName("update Name");user.setPassword("1111");user.setNickName("update nickName");
// deleteem.remove(user);
요구사항 변경 전 요구사항 변경 후
![Page 33: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/33.jpg)
모든 Domain은 변경된다.
![Page 34: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/34.jpg)
● type safe 하지 않고
● 실수할 확률이 높고
● 수정해야 할 코드가 많아지며
● 단순 CRUD 코드를 반복한다.
![Page 35: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/35.jpg)
객체와 테이블
![Page 36: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/36.jpg)
테이블 지향 엔티티public class User {
private int userId;
private String name;
private String password;
private String nickName;
}
public class Board {
private int boardId;
// foreign keyprivate int userId;
private String title;
private String content;
}
![Page 37: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/37.jpg)
객체 지향 엔티티public class User {
private int userId;
private String name;
private String password;
private String nickName;
}
public class Board {
private int boardId;
// object referenceprivate User user;
private String title;
private String content;
}
![Page 38: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/38.jpg)
● 객체 그래프 탐색
● 테이블과 객체 간 연관 관계 불일치
● Query 작성 증가
![Page 39: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/39.jpg)
엔티티 생명주기
![Page 40: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/40.jpg)
● New(비영속) : DB에 반영 되지 않고 영속성 컨텍스트와 관
계 없는 엔티티
● Managed(영속) : 영속성 컨텍스트에 저장된 엔티티
● Detached(준영속) : 영속성 컨텍스트에서 분리된 엔티티
● Removed(삭제) : 삭제된 엔티티
![Page 41: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/41.jpg)
![Page 42: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/42.jpg)
비영속 그리고 준영속
![Page 43: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/43.jpg)
// 비 영속User newUser = new User(“name”, “password”, “nickName”);
// 준 영속User detachUser = new User(1, “name”, “password”, “nickName”);
![Page 44: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/44.jpg)
detachUser.userId가
DB에 있는 경우 “준영속”
![Page 45: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/45.jpg)
영속성 컨텍스트
![Page 46: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/46.jpg)
● 쓰기 지연 SQL
● 자동 변경 감지
● 1차 캐시
● 엔티티 동일성
● 지연 로딩
![Page 47: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/47.jpg)
영속성 컨텍스트는 어떻게 동작할까?
![Page 48: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/48.jpg)
@Entity@Table(name = "User")public class User {
@Id @GeneratedValueprivate 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;
}
![Page 49: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/49.jpg)
입력(persist)
![Page 50: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/50.jpg)
EntityManager em = emf.createEntityManager();em.getTransaction().begin();
// 비 영속 상태User user = new User("wons", "12345", "woniper");
// 영속 상태 // 1차 캐시 저장em.persist(user);
// 준영속 상태// SQL 저장소 쿼리 반영em.getTransaction().commit();em.close();
![Page 51: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/51.jpg)
![Page 52: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/52.jpg)
![Page 53: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/53.jpg)
![Page 54: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/54.jpg)
조회(find)
![Page 55: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/55.jpg)
EntityManager em = emf.createEntityManager();em.getTransaction().begin();
// 영속 엔티티// 1차 캐시 저장User user = em.find(User.class, user.getUserId());
// 준영속 상태em.getTransaction().commit();em.close();
![Page 56: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/56.jpg)
![Page 57: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/57.jpg)
![Page 58: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/58.jpg)
![Page 59: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/59.jpg)
수정(자동 변경 감지)
![Page 60: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/60.jpg)
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();
![Page 61: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/61.jpg)
![Page 62: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/62.jpg)
![Page 63: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/63.jpg)
![Page 64: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/64.jpg)
삭제(remove)
![Page 65: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/65.jpg)
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();
![Page 66: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/66.jpg)
![Page 67: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/67.jpg)
![Page 68: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/68.jpg)
![Page 69: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/69.jpg)
지금까지 모든 일은 트랜젝션
작업 단위에서 동작
![Page 70: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/70.jpg)
사실 commit은
EntityManager.flush()를 먼저 호출
![Page 71: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/71.jpg)
flush()는 영속성 컨텍스트와 DB를 동기화
![Page 72: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/72.jpg)
merge
![Page 73: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/73.jpg)
준 영속 엔티티 -> 영속 엔티티
![Page 74: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/74.jpg)
merge를 알아보기 전에
![Page 75: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/75.jpg)
영속 엔티티 -> 준 영속 엔티티
![Page 76: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/76.jpg)
● em.clear();
● em.detach(user);
● em.getTransaction().commit();
![Page 77: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/77.jpg)
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();
![Page 78: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/78.jpg)
EntityManager em = emf.createEntityManager();em.getTransaction().begin();
// 5. name 속성 값은?User user2 = em.find(User.class, 1);
em.getTransaction().commit();em.close();
![Page 79: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/79.jpg)
● 속성이 변경된 준영속 엔티티 merge : update
● 비영속 엔티티 merge : insert
![Page 80: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/80.jpg)
즉 merge는 영속 엔티티로 만들기도 하지
만
update 또는 insert 하기도 함
![Page 81: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/81.jpg)
준 영속 상태는 영속성 컨텍스트
특징을 사용하지 못하는 것
![Page 82: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/82.jpg)
● 쓰기 지연 SQL
● 자동 변경 감지
● 1차 캐시
● 엔티티 동일성
● 지연 로딩
![Page 83: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/83.jpg)
Spring Data JPA
![Page 84: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/84.jpg)
소개 정도만 할게요.
![Page 85: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/85.jpg)
@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;}
![Page 86: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/86.jpg)
Repository Interface
![Page 87: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/87.jpg)
public interface UserRepository extends JpaRepository<User, Integer> {}
![Page 88: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/88.jpg)
Repository 만 추가 하면
![Page 89: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/89.jpg)
● save(T);● delete(T);● findOne(ID);● findAll();● findAll(Pageable);
![Page 90: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/90.jpg)
CRUD 그 외 조회 Query가
필요하다면?
![Page 92: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/92.jpg)
method 이름으로 Query생성
![Page 93: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/93.jpg)
정확히 말하면 JPQL 생성
![Page 94: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/94.jpg)
물론 규칙을 지켜 method 이름 설정
![Page 95: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/95.jpg)
public interface UserRepository extends JpaRepository<User, Integer> {
// where u.name = ?nameUser findByName(String name);
// where u.name = ?name and u.password = ?password;User findByNameAndPassword(String name, String password);
}
![Page 96: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/96.jpg)
참고자료
![Page 97: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/97.jpg)
![Page 98: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/98.jpg)
● http://www.tutorialspoint.com/jpa/● http://www.objectdb.com/● https://en.wikibooks.
org/wiki/Java_Persistence
![Page 99: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/99.jpg)
● http://goo.gl/xzpTdK● https://goo.gl/sqmO9p● https://goo.gl/GhsI4Q● https://goo.gl/GpQzeL
![Page 100: Jpa 잘 (하는 척) 하기](https://reader034.vdocuments.net/reader034/viewer/2022050613/587c972c1a28abfa5e8b64a7/html5/thumbnails/100.jpg)
QnA